Full Code of keephq/keep for AI

main 2403b2b71042 cached
2212 files
8.9 MB
2.5M tokens
5841 symbols
1 requests
Download .txt
Showing preview only (9,822K chars total). Download the full file or copy to clipboard to get everything.
Repository: keephq/keep
Branch: main
Commit: 2403b2b71042
Files: 2212
Total size: 8.9 MB

Directory structure:
gitextract_gaok0hlb/

├── .cursor/
│   └── rules/
│       ├── keep-ui-react-typescript.mdc
│       └── keep-ui-tests.mdc
├── .dockerignore
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── config.yml
│   │   ├── documentation.md
│   │   ├── feature_request.md
│   │   ├── new_provider_request.md
│   │   └── use_case.md
│   └── workflows/
│       ├── auto-release.yml
│       ├── auto-resolve-keep.yml
│       ├── but-to-project.yml
│       ├── developer-onboarding-notification.yml
│       ├── lint-pr.yml
│       ├── release-workflow-schema.yml
│       ├── release.yml
│       ├── run-e2e-tests.yml
│       ├── sync-keep-workflows.yml
│       ├── test-docs.yml
│       ├── test-pr-e2e.yml
│       ├── test-pr-integrations.yml
│       ├── test-pr-ut-ui.yml
│       ├── test-pr-ut.yml
│       └── test-workflow-examples.yml
├── .gitignore
├── .pre-commit-config.yaml
├── .python-version
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── docker/
│   ├── Dockerfile.api
│   ├── Dockerfile.cli
│   ├── Dockerfile.dev.api
│   ├── Dockerfile.dev.ui
│   └── Dockerfile.ui
├── docker-compose-with-arq.yml
├── docker-compose-with-auth.yml
├── docker-compose-with-otel.yaml
├── docker-compose.common.yml
├── docker-compose.dev.yml
├── docker-compose.yml
├── docs/
│   ├── README.md
│   ├── alertevaluation/
│   │   ├── examples/
│   │   │   ├── victoriametricsmulti.mdx
│   │   │   └── victoriametricssingle.mdx
│   │   └── overview.mdx
│   ├── alerts/
│   │   ├── actionmenu.mdx
│   │   ├── overview.mdx
│   │   ├── presets.mdx
│   │   ├── sidebar.mdx
│   │   ├── sound.mdx
│   │   └── table.mdx
│   ├── applications/
│   │   └── github.mdx
│   ├── authentication/
│   │   └── okta.md
│   ├── cli/
│   │   ├── commands/
│   │   │   ├── alert-enrich.mdx
│   │   │   ├── alert-get.mdx
│   │   │   ├── alert-list.mdx
│   │   │   ├── cli-alert.mdx
│   │   │   ├── cli-api.mdx
│   │   │   ├── cli-config-new.mdx
│   │   │   ├── cli-config-show.mdx
│   │   │   ├── cli-config.mdx
│   │   │   ├── cli-provider.mdx
│   │   │   ├── cli-run.mdx
│   │   │   ├── cli-version.mdx
│   │   │   ├── cli-whoami.mdx
│   │   │   ├── cli-workflow.mdx
│   │   │   ├── cli.mdx
│   │   │   ├── extraction-create.mdx
│   │   │   ├── extraction-delete.mdx
│   │   │   ├── extractions-list.mdx
│   │   │   ├── mappings-create.mdx
│   │   │   ├── mappings-delete.mdx
│   │   │   ├── mappings-list.mdx
│   │   │   ├── provider-connect.mdx
│   │   │   ├── provider-delete.mdx
│   │   │   ├── provider-list.mdx
│   │   │   ├── runs-list.mdx
│   │   │   ├── runs-logs.mdx
│   │   │   ├── workflow-apply.mdx
│   │   │   ├── workflow-list.mdx
│   │   │   ├── workflow-run.mdx
│   │   │   └── workflow-runs.mdx
│   │   ├── github-actions.mdx
│   │   ├── installation.mdx
│   │   └── overview.mdx
│   ├── deployment/
│   │   ├── authentication/
│   │   │   ├── auth0-auth.mdx
│   │   │   ├── azuread-auth.mdx
│   │   │   ├── db-auth.mdx
│   │   │   ├── keycloak-auth.mdx
│   │   │   ├── no-auth.mdx
│   │   │   ├── oauth2-proxy-gitlab.mdx
│   │   │   ├── oauth2proxy-auth.mdx
│   │   │   ├── okta-auth.mdx
│   │   │   ├── onelogin-auth.mdx
│   │   │   └── overview.mdx
│   │   ├── configuration.mdx
│   │   ├── docker.mdx
│   │   ├── ecs.mdx
│   │   ├── kubernetes/
│   │   │   ├── architecture.mdx
│   │   │   ├── installation.mdx
│   │   │   ├── openshift.mdx
│   │   │   └── overview.mdx
│   │   ├── local-llm/
│   │   │   └── keep-with-litellm.mdx
│   │   ├── monitoring.mdx
│   │   ├── provision/
│   │   │   ├── dashboard.mdx
│   │   │   ├── overview.mdx
│   │   │   ├── provider.mdx
│   │   │   └── workflow.mdx
│   │   ├── secret-store.mdx
│   │   └── stress-testing.mdx
│   ├── development/
│   │   ├── external-url.mdx
│   │   └── getting-started.mdx
│   ├── images/
│   │   └── datadog_raw_alerts.txt
│   ├── incidents/
│   │   ├── facets.mdx
│   │   └── overview.mdx
│   ├── mint.json
│   ├── openapi.json
│   ├── overview/
│   │   ├── ai-correlation.mdx
│   │   ├── ai-in-workflows.mdx
│   │   ├── ai-incident-assistant.mdx
│   │   ├── ai-semi-automatic-correlation.mdx
│   │   ├── ai-workflow-assistant.mdx
│   │   ├── alertseverityandstatus.mdx
│   │   ├── cel.mdx
│   │   ├── comparisons.mdx
│   │   ├── correlation-rules.mdx
│   │   ├── correlation-topology.mdx
│   │   ├── deduplication.mdx
│   │   ├── enrichment/
│   │   │   ├── extraction.mdx
│   │   │   └── mapping.mdx
│   │   ├── faq.mdx
│   │   ├── fingerprints.mdx
│   │   ├── glossary.mdx
│   │   ├── howdoeskeepgetmyalerts.mdx
│   │   ├── introduction.mdx
│   │   ├── maintenance-windows.mdx
│   │   ├── playground.mdx
│   │   ├── servicetopology.mdx
│   │   ├── support.mdx
│   │   ├── usecases.mdx
│   │   └── workflow-automation.mdx
│   ├── providers/
│   │   ├── adding-a-new-provider.mdx
│   │   ├── documentation/
│   │   │   ├── airflow-provider.mdx
│   │   │   ├── aks-provider.mdx
│   │   │   ├── amazonsqs-provider.mdx
│   │   │   ├── anthropic-provider.mdx
│   │   │   ├── appdynamics-provider.mdx
│   │   │   ├── argocd-provider.mdx
│   │   │   ├── asana-provider.mdx
│   │   │   ├── auth0-provider.mdx
│   │   │   ├── axiom-provider.mdx
│   │   │   ├── azuremonitoring-provider.mdx
│   │   │   ├── bash-provider.mdx
│   │   │   ├── bigquery-provider.mdx
│   │   │   ├── centreon-provider.mdx
│   │   │   ├── checkly-provider.mdx
│   │   │   ├── checkmk-provider.mdx
│   │   │   ├── cilium-provider.mdx
│   │   │   ├── clickhouse-provider.mdx
│   │   │   ├── cloudwatch-provider.mdx
│   │   │   ├── console-provider.mdx
│   │   │   ├── coralogix-provider.mdx
│   │   │   ├── dash0-provider.mdx
│   │   │   ├── databend-provider.mdx
│   │   │   ├── datadog-provider.mdx
│   │   │   ├── deepseek-provider.mdx
│   │   │   ├── discord-provider.mdx
│   │   │   ├── dynatrace-provider.mdx
│   │   │   ├── eks-provider.mdx
│   │   │   ├── elastic-provider.mdx
│   │   │   ├── flashduty-provider.mdx
│   │   │   ├── fluxcd-provider.mdx
│   │   │   ├── gcpmonitoring-provider.mdx
│   │   │   ├── gemini-provider.mdx
│   │   │   ├── github-provider.mdx
│   │   │   ├── github_workflows_provider.mdx
│   │   │   ├── gitlab-provider.mdx
│   │   │   ├── gitlabpipelines-provider.mdx
│   │   │   ├── gke-provider.mdx
│   │   │   ├── google_chat-provider.mdx
│   │   │   ├── grafana-provider.mdx
│   │   │   ├── grafana_incident-provider.mdx
│   │   │   ├── grafana_loki-provider.mdx
│   │   │   ├── grafana_oncall-provider.mdx
│   │   │   ├── graylog-provider.mdx
│   │   │   ├── grok-provider.mdx
│   │   │   ├── http-provider.mdx
│   │   │   ├── icinga2-provider.mdx
│   │   │   ├── ilert-provider.mdx
│   │   │   ├── incidentio-provider.mdx
│   │   │   ├── incidentmanager-provider.mdx
│   │   │   ├── jira-on-prem-provider.mdx
│   │   │   ├── jira-provider.mdx
│   │   │   ├── kafka-provider.mdx
│   │   │   ├── keep-provider.mdx
│   │   │   ├── kibana-provider.mdx
│   │   │   ├── kubernetes-provider.mdx
│   │   │   ├── libre_nms-provider.mdx
│   │   │   ├── linear_provider.mdx
│   │   │   ├── linearb-provider.mdx
│   │   │   ├── litellm-provider.mdx
│   │   │   ├── llamacpp-provider.mdx
│   │   │   ├── mailgun-provider.mdx
│   │   │   ├── mattermost-provider.mdx
│   │   │   ├── mock-provider.mdx
│   │   │   ├── monday-provider.mdx
│   │   │   ├── mongodb-provider.mdx
│   │   │   ├── mysql-provider.mdx
│   │   │   ├── netbox-provider.mdx
│   │   │   ├── netdata-provider.mdx
│   │   │   ├── new-relic-provider.mdx
│   │   │   ├── ntfy-provider.mdx
│   │   │   ├── ollama-provider.mdx
│   │   │   ├── openai-provider.mdx
│   │   │   ├── openobserve-provider.mdx
│   │   │   ├── opensearchserverless-provider.mdx
│   │   │   ├── openshift-provider.mdx
│   │   │   ├── opsgenie-provider.mdx
│   │   │   ├── pagerduty-provider.mdx
│   │   │   ├── pagertree-provider.mdx
│   │   │   ├── parseable-provider.mdx
│   │   │   ├── pingdom-provider.mdx
│   │   │   ├── planner-provider.mdx
│   │   │   ├── postgresql-provider.mdx
│   │   │   ├── posthog-provider.mdx
│   │   │   ├── prometheus-provider.mdx
│   │   │   ├── pushover-provider.mdx
│   │   │   ├── python-provider.mdx
│   │   │   ├── quickchart-provider.mdx
│   │   │   ├── redmine-provider.mdx
│   │   │   ├── resend-provider.mdx
│   │   │   ├── rollbar-provider.mdx
│   │   │   ├── s3-provider.mdx
│   │   │   ├── sendgrid-provider.mdx
│   │   │   ├── sentry-provider.mdx
│   │   │   ├── service-now-provider.mdx
│   │   │   ├── signalfx-provider.mdx
│   │   │   ├── signl4-provider.mdx
│   │   │   ├── site24x7-provider.mdx
│   │   │   ├── slack-provider.mdx
│   │   │   ├── smtp-provider.mdx
│   │   │   ├── snowflake-provider.mdx
│   │   │   ├── splunk-provider.mdx
│   │   │   ├── squadcast-provider.mdx
│   │   │   ├── ssh-provider.mdx
│   │   │   ├── statuscake-provider.mdx
│   │   │   ├── sumologic-provider.mdx
│   │   │   ├── teams-provider.mdx
│   │   │   ├── telegram-provider.mdx
│   │   │   ├── template.mdx
│   │   │   ├── thousandeyes-provider.mdx
│   │   │   ├── trello-provider.mdx
│   │   │   ├── twilio-provider.mdx
│   │   │   ├── uptimekuma-provider.mdx
│   │   │   ├── victorialogs-provider.mdx
│   │   │   ├── victoriametrics-provider.mdx
│   │   │   ├── vllm-provider.mdx
│   │   │   ├── wazuh-provider.mdx
│   │   │   ├── webhook-provider.mdx
│   │   │   ├── websocket-provider.mdx
│   │   │   ├── youtrack-provider.mdx
│   │   │   ├── zabbix-provider.mdx
│   │   │   ├── zenduty-provider.mdx
│   │   │   ├── zoom-provider.mdx
│   │   │   └── zoom_chat-provider.mdx
│   │   ├── linked-providers.mdx
│   │   ├── overview.md
│   │   ├── overview.mdx
│   │   └── provider-methods.mdx
│   ├── snippets/
│   │   └── providers/
│   │       ├── airflow-snippet-autogenerated.mdx
│   │       ├── aks-snippet-autogenerated.mdx
│   │       ├── amazonsqs-snippet-autogenerated.mdx
│   │       ├── anthropic-snippet-autogenerated.mdx
│   │       ├── appdynamics-snippet-autogenerated.mdx
│   │       ├── argocd-snippet-autogenerated.mdx
│   │       ├── asana-snippet-autogenerated.mdx
│   │       ├── auth0-snippet-autogenerated.mdx
│   │       ├── axiom-snippet-autogenerated.mdx
│   │       ├── azuremonitoring-snippet-autogenerated.mdx
│   │       ├── base-snippet-autogenerated.mdx
│   │       ├── bash-snippet-autogenerated.mdx
│   │       ├── bigquery-snippet-autogenerated.mdx
│   │       ├── centreon-snippet-autogenerated.mdx
│   │       ├── checkly-snippet-autogenerated.mdx
│   │       ├── checkmk-snippet-autogenerated.mdx
│   │       ├── cilium-snippet-autogenerated.mdx
│   │       ├── clickhouse-snippet-autogenerated.mdx
│   │       ├── cloudwatch-snippet-autogenerated.mdx
│   │       ├── console-snippet-autogenerated.mdx
│   │       ├── coralogix-snippet-autogenerated.mdx
│   │       ├── dash0-snippet-autogenerated.mdx
│   │       ├── databend-snippet-autogenerated.mdx
│   │       ├── datadog-snippet-autogenerated.mdx
│   │       ├── deepseek-snippet-autogenerated.mdx
│   │       ├── discord-snippet-autogenerated.mdx
│   │       ├── dynatrace-snippet-autogenerated.mdx
│   │       ├── eks-snippet-autogenerated.mdx
│   │       ├── elastic-snippet-autogenerated.mdx
│   │       ├── flashduty-snippet-autogenerated.mdx
│   │       ├── fluxcd-snippet-autogenerated.mdx
│   │       ├── gcpmonitoring-snippet-autogenerated.mdx
│   │       ├── gemini-snippet-autogenerated.mdx
│   │       ├── github-snippet-autogenerated.mdx
│   │       ├── github_workflows-snippet-autogenerated.mdx
│   │       ├── gitlab-snippet-autogenerated.mdx
│   │       ├── gitlabpipelines-snippet-autogenerated.mdx
│   │       ├── gke-snippet-autogenerated.mdx
│   │       ├── google_chat-snippet-autogenerated.mdx
│   │       ├── grafana-snippet-autogenerated.mdx
│   │       ├── grafana_incident-snippet-autogenerated.mdx
│   │       ├── grafana_loki-snippet-autogenerated.mdx
│   │       ├── grafana_oncall-snippet-autogenerated.mdx
│   │       ├── graylog-snippet-autogenerated.mdx
│   │       ├── grok-snippet-autogenerated.mdx
│   │       ├── http-snippet-autogenerated.mdx
│   │       ├── icinga2-snippet-autogenerated.mdx
│   │       ├── ilert-snippet-autogenerated.mdx
│   │       ├── incidentio-snippet-autogenerated.mdx
│   │       ├── incidentmanager-snippet-autogenerated.mdx
│   │       ├── jira-snippet-autogenerated.mdx
│   │       ├── jiraonprem-snippet-autogenerated.mdx
│   │       ├── kafka-snippet-autogenerated.mdx
│   │       ├── keep-snippet-autogenerated.mdx
│   │       ├── kibana-snippet-autogenerated.mdx
│   │       ├── kubernetes-snippet-autogenerated.mdx
│   │       ├── libre_nms-snippet-autogenerated.mdx
│   │       ├── linear-snippet-autogenerated.mdx
│   │       ├── linearb-snippet-autogenerated.mdx
│   │       ├── litellm-snippet-autogenerated.mdx
│   │       ├── llamacpp-snippet-autogenerated.mdx
│   │       ├── mailgun-snippet-autogenerated.mdx
│   │       ├── mattermost-snippet-autogenerated.mdx
│   │       ├── mock-snippet-autogenerated.mdx
│   │       ├── monday-snippet-autogenerated.mdx
│   │       ├── mongodb-snippet-autogenerated.mdx
│   │       ├── mysql-snippet-autogenerated.mdx
│   │       ├── netbox-snippet-autogenerated.mdx
│   │       ├── netdata-snippet-autogenerated.mdx
│   │       ├── netxms-snippet-autogenerated.mdx
│   │       ├── newrelic-snippet-autogenerated.mdx
│   │       ├── ntfy-snippet-autogenerated.mdx
│   │       ├── ollama-snippet-autogenerated.mdx
│   │       ├── openai-snippet-autogenerated.mdx
│   │       ├── openobserve-snippet-autogenerated.mdx
│   │       ├── opensearchserverless-snippet-autogenerated.mdx
│   │       ├── openshift-snippet-autogenerated.mdx
│   │       ├── opsgenie-snippet-autogenerated.mdx
│   │       ├── pagerduty-snippet-autogenerated.mdx
│   │       ├── pagertree-snippet-autogenerated.mdx
│   │       ├── parseable-snippet-autogenerated.mdx
│   │       ├── pingdom-snippet-autogenerated.mdx
│   │       ├── planner-snippet-autogenerated.mdx
│   │       ├── postgres-snippet-autogenerated.mdx
│   │       ├── posthog-snippet-autogenerated.mdx
│   │       ├── prometheus-snippet-autogenerated.mdx
│   │       ├── pushover-snippet-autogenerated.mdx
│   │       ├── python-snippet-autogenerated.mdx
│   │       ├── quickchart-snippet-autogenerated.mdx
│   │       ├── redmine-snippet-autogenerated.mdx
│   │       ├── resend-snippet-autogenerated.mdx
│   │       ├── rollbar-snippet-autogenerated.mdx
│   │       ├── s3-snippet-autogenerated.mdx
│   │       ├── salesforce-snippet-autogenerated.mdx
│   │       ├── sendgrid-snippet-autogenerated.mdx
│   │       ├── sentry-snippet-autogenerated.mdx
│   │       ├── servicenow-snippet-autogenerated.mdx
│   │       ├── signalfx-snippet-autogenerated.mdx
│   │       ├── signl4-snippet-autogenerated.mdx
│   │       ├── site24x7-snippet-autogenerated.mdx
│   │       ├── slack-snippet-autogenerated.mdx
│   │       ├── smtp-snippet-autogenerated.mdx
│   │       ├── snowflake-snippet-autogenerated.mdx
│   │       ├── splunk-snippet-autogenerated.mdx
│   │       ├── squadcast-snippet-autogenerated.mdx
│   │       ├── ssh-snippet-autogenerated.mdx
│   │       ├── statuscake-snippet-autogenerated.mdx
│   │       ├── sumologic-snippet-autogenerated.mdx
│   │       ├── teams-snippet-autogenerated.mdx
│   │       ├── telegram-snippet-autogenerated.mdx
│   │       ├── test_fluxcd-snippet-autogenerated.mdx
│   │       ├── thousandeyes-snippet-autogenerated.mdx
│   │       ├── trello-snippet-autogenerated.mdx
│   │       ├── twilio-snippet-autogenerated.mdx
│   │       ├── uptimekuma-snippet-autogenerated.mdx
│   │       ├── vectordev-snippet-autogenerated.mdx
│   │       ├── victorialogs-snippet-autogenerated.mdx
│   │       ├── victoriametrics-snippet-autogenerated.mdx
│   │       ├── vllm-snippet-autogenerated.mdx
│   │       ├── wazuh-snippet-autogenerated.mdx
│   │       ├── webhook-snippet-autogenerated.mdx
│   │       ├── websocket-snippet-autogenerated.mdx
│   │       ├── youtrack-snippet-autogenerated.mdx
│   │       ├── zabbix-snippet-autogenerated.mdx
│   │       ├── zendesk-snippet-autogenerated.mdx
│   │       ├── zenduty-snippet-autogenerated.mdx
│   │       ├── zoom-snippet-autogenerated.mdx
│   │       └── zoom_chat-snippet-autogenerated.mdx
│   └── workflows/
│       ├── examples/
│       │   ├── autosupress.mdx
│       │   ├── buisnesshours.mdx
│       │   ├── create-servicenow-tickets.mdx
│       │   ├── highsev.mdx
│       │   └── update-servicenow-tickets.mdx
│       ├── overview.mdx
│       └── syntax/
│           ├── conditions.mdx
│           ├── context.mdx
│           ├── enrichment.mdx
│           ├── foreach.mdx
│           ├── functions.mdx
│           ├── permissions.mdx
│           ├── providers.mdx
│           ├── steps-and-actions.mdx
│           └── triggers.mdx
├── ee/
│   ├── LICENSE
│   └── identitymanager/
│       ├── __init__.py
│       └── identity_managers/
│           ├── __init__.py
│           ├── auth0/
│           │   ├── __init__.py
│           │   ├── auth0_authverifier.py
│           │   ├── auth0_identitymanager.py
│           │   └── auth0_utils.py
│           ├── azuread/
│           │   ├── __init__.py
│           │   ├── azuread_authverifier.py
│           │   └── azuread_identitymanager.py
│           └── keycloak/
│               ├── __init__.py
│               ├── keycloak_authverifier.py
│               └── keycloak_identitymanager.py
├── elk/
│   ├── README.md
│   ├── docker-compose-elk.yml
│   ├── filebeat.yml
│   └── logstash.conf
├── examples/
│   ├── providers/
│   │   ├── airflow-prod.yaml
│   │   └── telegram-bot.yaml
│   └── workflows/
│       ├── aks_basic.yml
│       ├── autosupress.yml
│       ├── bash_example.yml
│       ├── bigquery.yml
│       ├── blogpost.yml
│       ├── businesshours.yml
│       ├── change.yml
│       ├── clickhouse_multiquery.yml
│       ├── complex-conditions-cel.yml
│       ├── conditionally_run_if_ai_says_so.yaml
│       ├── console_example.yml
│       ├── consts_and_dict.yml
│       ├── consts_and_vars.yml
│       ├── create-issue-youtrack.yaml
│       ├── create-new-incident-grafana-incident.yaml
│       ├── create-task-in-asana.yaml
│       ├── create_alert_from_vm_metric.yml
│       ├── create_alert_in_keep.yml
│       ├── create_alerts_from_elastic.yml
│       ├── create_alerts_from_mysql.yml
│       ├── create_jira_ticket_upon_alerts.yml
│       ├── create_multi_alert_from_vm_metric.yml
│       ├── create_service_now_ticket_upon_alerts.yml
│       ├── datadog-log-monitor.yml
│       ├── db_disk_space_monitor.yml
│       ├── discord_basic.yml
│       ├── disk_grown_defects_rule.yml
│       ├── eks_advanced.yml
│       ├── eks_basic.yml
│       ├── elastic_basic.yml
│       ├── elastic_enrich_example.yml
│       ├── enrich_using_structured_output_from_deepseek.yaml
│       ├── enrich_using_structured_output_from_openai.yaml
│       ├── enrich_using_structured_output_from_vllm_qwen.yaml
│       ├── failed-to-login-workflow.yml
│       ├── flashduty_example.yml
│       ├── fluxcd_example.yml
│       ├── gcp_logging_open_ai.yaml
│       ├── gke.yml
│       ├── http_enrich.yml
│       ├── ifelse.yml
│       ├── ilert-incident-upon-alert.yaml
│       ├── incident-enrich.yaml
│       ├── incident-tier-escalation.yml
│       ├── incident_example.yml
│       ├── inputs_example.yml
│       ├── jira-create-ticket-on-alert.yml
│       ├── jira-transition-on-resolved.yml
│       ├── jira_on_prem.yml
│       ├── monday_create_pulse.yml
│       ├── multi-condition-cel.yml
│       ├── mustache-paths-example.yml
│       ├── new-auth0-users-monitor.yml
│       ├── new_github_stars.yml
│       ├── notify-new-trello-card.yml
│       ├── ntfy_basic.yml
│       ├── opensearchserverless_basic.yml
│       ├── openshift_basic.yml
│       ├── openshift_monitoring_and_remediation.yml
│       ├── openshift_pod_restart.yml
│       ├── opsgenie-close-alert.yml
│       ├── opsgenie-create-alert-cel.yml
│       ├── opsgenie-create-alert.yml
│       ├── opsgenie_open_alerts.yml
│       ├── pagerduty.yml
│       ├── pattern-matching-cel.yml
│       ├── permissions_example.yml
│       ├── planner_basic.yml
│       ├── posthog_example.yml
│       ├── query-databend.yml
│       ├── query_clickhouse.yml
│       ├── query_grafana_loki.yaml
│       ├── query_mongodb.yaml
│       ├── query_victorialogs.yaml
│       ├── query_victoriametrics.yml
│       ├── raw_sql_query_datetime.yml
│       ├── resolve_old_alerts.yml
│       ├── retrieve_cloudwatch_logs.yaml
│       ├── run-github-workflow.yaml
│       ├── send-message-telegram-with-htmlmd.yaml
│       ├── send_slack_message_on_failure.yaml
│       ├── send_smtp_email.yml
│       ├── send_smtp_html_email.yml
│       ├── sendgrid_basic.yml
│       ├── service-error-rate-monitor-datadog.yml
│       ├── severity_changed.yml
│       ├── signl4-alerting-workflow.yaml
│       ├── simple_http_request_ntfy.yml
│       ├── slack-message-reaction.yml
│       ├── slack-workflow-trigger.yml
│       ├── slack_basic.yml
│       ├── slack_basic_cel.yml
│       ├── slack_basic_interval.yml
│       ├── slack_message_update.yml
│       ├── squadcast_example.yml
│       ├── teams-adaptive-card-notifier.yaml
│       ├── teams-adaptive-cards-with-mentions.yaml
│       ├── telegram_advanced.yml
│       ├── telegram_basic.yml
│       ├── test_jira_create_with_custom_fields.yml
│       ├── test_jira_custom_fields_fix.yml
│       ├── update-incident-grafana-incident.yaml
│       ├── update-task-in-asana.yaml
│       ├── update_jira_ticket.yml
│       ├── update_service_now_tickets_status.yml
│       ├── update_workflows_from_http.yml
│       ├── update_workflows_from_s3.yml
│       ├── webhook_example.yml
│       ├── webhook_example_foreach.yml
│       ├── workflow_only_first_time_example.yml
│       ├── workflow_start_example.yml
│       ├── zoom_chat_example.yml
│       └── zoom_example.yml
├── keep/
│   ├── actions/
│   │   ├── __init__.py
│   │   ├── actions_exception.py
│   │   └── actions_factory.py
│   ├── alembic.ini
│   ├── api/
│   │   ├── __init__.py
│   │   ├── alert_deduplicator/
│   │   │   ├── __init__.py
│   │   │   ├── alert_deduplicator.py
│   │   │   └── deduplication_rules_provisioning.py
│   │   ├── api.py
│   │   ├── arq_pool.py
│   │   ├── arq_worker.py
│   │   ├── arq_worker_debug_patch.py
│   │   ├── arq_worker_gunicorn.py
│   │   ├── bl/
│   │   │   ├── ai_suggestion_bl.py
│   │   │   ├── dismissal_expiry_bl.py
│   │   │   ├── enrichments_bl.py
│   │   │   ├── incident_reports.py
│   │   │   ├── incidents_bl.py
│   │   │   └── maintenance_windows_bl.py
│   │   ├── config.py
│   │   ├── consts.py
│   │   ├── core/
│   │   │   ├── alerts.py
│   │   │   ├── cel_to_sql/
│   │   │   │   ├── ast_nodes.py
│   │   │   │   ├── cel_ast_converter.py
│   │   │   │   ├── properties_mapper.py
│   │   │   │   ├── properties_metadata.py
│   │   │   │   └── sql_providers/
│   │   │   │       ├── base.py
│   │   │   │       ├── get_cel_to_sql_provider_for_dialect.py
│   │   │   │       ├── mysql.py
│   │   │   │       ├── postgresql.py
│   │   │   │       └── sqlite.py
│   │   │   ├── config.py
│   │   │   ├── db.py
│   │   │   ├── db_on_start.py
│   │   │   ├── db_utils.py
│   │   │   ├── demo_mode.py
│   │   │   ├── dependencies.py
│   │   │   ├── elastic.py
│   │   │   ├── facets.py
│   │   │   ├── facets_query_builder/
│   │   │   │   ├── base_facets_query_builder.py
│   │   │   │   ├── get_facets_query_builder.py
│   │   │   │   ├── mysql.py
│   │   │   │   ├── postgresql.py
│   │   │   │   ├── sqlite.py
│   │   │   │   └── utils.py
│   │   │   ├── incidents.py
│   │   │   ├── limiter.py
│   │   │   ├── metrics.py
│   │   │   ├── report_uptime.py
│   │   │   ├── tenant_configuration.py
│   │   │   ├── tracer.py
│   │   │   └── workflows.py
│   │   ├── custom_worker.py
│   │   ├── logging.py
│   │   ├── middlewares.py
│   │   ├── models/
│   │   │   ├── __init__.py
│   │   │   ├── action.py
│   │   │   ├── action_type.py
│   │   │   ├── ai_external.py
│   │   │   ├── alert.py
│   │   │   ├── alert_audit.py
│   │   │   ├── db/
│   │   │   │   ├── action.py
│   │   │   │   ├── ai_external.py
│   │   │   │   ├── ai_suggestion.py
│   │   │   │   ├── alert.py
│   │   │   │   ├── dashboard.py
│   │   │   │   ├── enrichment_event.py
│   │   │   │   ├── extraction.py
│   │   │   │   ├── facet.py
│   │   │   │   ├── helpers.py
│   │   │   │   ├── incident.py
│   │   │   │   ├── maintenance_window.py
│   │   │   │   ├── mapping.py
│   │   │   │   ├── migrations/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── env.py
│   │   │   │   │   ├── script.py.mako
│   │   │   │   │   └── versions/
│   │   │   │   │       ├── 2024-07-11-17-10_54c1252b2c8a.py
│   │   │   │   │       ├── 2024-07-15-15-10_c37ec8f6db3e.py
│   │   │   │   │       ├── 2024-07-16-12-16_37019ca3eb2e.py
│   │   │   │   │       ├── 2024-07-17-16-46_dcbd2873dcfd.py
│   │   │   │   │       ├── 2024-07-24-13-39_9ba0aeecd4d0.py
│   │   │   │   │       ├── 2024-07-25-17-13_67f1efb93c99.py
│   │   │   │   │       ├── 2024-07-28-16-24_8e5942040de6.py
│   │   │   │   │       ├── 2024-07-29-12-51_c91b348b94f2.py
│   │   │   │   │       ├── 2024-07-29-18-10_92f4f93f2140.py
│   │   │   │   │       ├── 2024-08-05-13-09_4147d9e706c0.py
│   │   │   │   │       ├── 2024-08-11-17-38_9453855f3ba0.py
│   │   │   │   │       ├── 2024-08-13-19-22_0832e0d9889a.py
│   │   │   │   │       ├── 2024-08-14-18-30_87594ea6d308.py
│   │   │   │   │       ├── 2024-08-25-16-40_4ef2c767664c.py
│   │   │   │   │       ├── 2024-08-25-16-48_1c650a429672.py
│   │   │   │   │       ├── 2024-08-30-09-34_7ed12220a0d3.py
│   │   │   │   │       ├── 2024-09-01-14-04_94886bc59c11.py
│   │   │   │   │       ├── 2024-09-02-12-07_70671c95028e.py
│   │   │   │   │       ├── 2024-09-03-10-08_49e7c02579db.py
│   │   │   │   │       ├── 2024-09-03-16-24_1a5eb7069f9a.py
│   │   │   │   │       ├── 2024-09-04-13-09_e6653be70b62.py
│   │   │   │   │       ├── 2024-09-08-17-51_1aacee84447e.py
│   │   │   │   │       ├── 2024-09-13-10-48_938b1aa62d5c.py
│   │   │   │   │       ├── 2024-09-17-23-30_c5443d9deb0f.py
│   │   │   │   │       ├── 2024-09-18-02-05_772790c2e50a.py
│   │   │   │   │       ├── 2024-09-18-14-08_5d7ae55efc6a.py
│   │   │   │   │       ├── 2024-09-19-15-26_493f217af6b6.py
│   │   │   │   │       ├── 2024-09-22-14-16_01ebe17218c0.py
│   │   │   │   │       ├── 2024-10-05-18-37_017d759805d9.py
│   │   │   │   │       ├── 2024-10-08-10-47_bf756df80e9d.py
│   │   │   │   │       ├── 2024-10-14-08-34_83c1020be97d.py
│   │   │   │   │       ├── 2024-10-22-10-38_8438f041ee0e.py
│   │   │   │   │       ├── 2024-10-23-15-21_89b4d3905d26.py
│   │   │   │   │       ├── 2024-10-26-17-03_3f056d747d9e.py
│   │   │   │   │       ├── 2024-10-29-18-37_991b30bcf0b9.py
│   │   │   │   │       ├── 2024-10-31-18-01_273b29f368b7.py
│   │   │   │   │       ├── 2024-11-03-10-49_ef0b5b0df41c.py
│   │   │   │   │       ├── 2024-11-08-20-58_895fe80117aa.py
│   │   │   │   │       ├── 2024-11-10-13-06_620b6c048091.py
│   │   │   │   │       ├── 2024-11-20-15-50_192157fd5788.py
│   │   │   │   │       ├── 2024-12-01-16-40_3ad5308e7200.py
│   │   │   │   │       ├── 2024-12-02-13-36_bdae8684d0b4.py
│   │   │   │   │       ├── 2024-12-02-20-42_c6e5594c99f8.py
│   │   │   │   │       ├── 2024-12-08-16-24_55cc64020f6d.py
│   │   │   │   │       ├── 2024-12-10-19-11_7297ae99cd21.py
│   │   │   │   │       ├── 2024-12-17-12-48_3d20d954e058.py
│   │   │   │   │       ├── 2024-12-23-17-22_0c5e002094a9.py
│   │   │   │   │       ├── 2024-12-23-18-49_4f8c4b185d5b.py
│   │   │   │   │       ├── 2025-01-01-09-59_dcb7f88a04da.py
│   │   │   │   │       ├── 2025-01-01-15-14_1c117f1accff.py
│   │   │   │   │       ├── 2025-01-08-19-20_8a4ec08f2d6b.py
│   │   │   │   │       ├── 2025-01-14-18-41_416155f25854.py
│   │   │   │   │       ├── 2025-01-16-14-00_e3f33e571c3c.py
│   │   │   │   │       ├── 2025-01-19-10-44_d359baaf0836.py
│   │   │   │   │       ├── 2025-01-26-15-25_8176d7153747.py
│   │   │   │   │       ├── 2025-02-05-15-46_e343054ae740.py
│   │   │   │   │       ├── 2025-02-10-12-05_908d95386e29.py
│   │   │   │   │       ├── 2025-02-11-12-59_21d314490e6a.py
│   │   │   │   │       ├── 2025-02-13-09-54_cfe08cc46950.py
│   │   │   │   │       ├── 2025-02-13-17-27_90e2d22edc6a.py
│   │   │   │   │       ├── 2025-02-18-18-09_876a424d8f06.py
│   │   │   │   │       ├── 2025-02-19-15-32_35ebba262eb0.py
│   │   │   │   │       ├── 2025-02-20-23-15_ea25d9402518.py
│   │   │   │   │       ├── 2025-02-25-14-20_a82154690f35.py
│   │   │   │   │       ├── 2025-03-05-15-55_0b80bda47ee2.py
│   │   │   │   │       ├── 2025-03-11-16-54_16309df224d1.py
│   │   │   │   │       ├── 2025-03-12-13-22_ab333148350e.py
│   │   │   │   │       ├── 2025-03-12-14-36_9f11356d8ed9.py
│   │   │   │   │       ├── 2025-03-12-14-46_ca74b4a04371.py
│   │   │   │   │       ├── 2025-03-13-14-08_c0e70149c9ec.py
│   │   │   │   │       ├── 2025-03-14-15-52_f3ecc7411f38.py
│   │   │   │   │       ├── 2025-03-16-11-08_aff0128aa8f1.py
│   │   │   │   │       ├── 2025-03-18-14-54_971abbbf0a2c.py
│   │   │   │   │       ├── 2025-03-20-09-37_c0880e315ebe.py
│   │   │   │   │       ├── 2025-03-24-14-26_2a6132b443ab.py
│   │   │   │   │       ├── 2025-03-30-10-53_e663a98b1142.py
│   │   │   │   │       ├── 2025-04-03-12-09_bdf252fbc1be.py
│   │   │   │   │       ├── 2025-04-04-21-48_0dafe96ea97f.py
│   │   │   │   │       ├── 2025-04-06-12-18_78777e6b12d3.py
│   │   │   │   │       ├── 2025-04-08-10-43_59991b568c7d.py
│   │   │   │   │       ├── 2025-04-15-15-30_885ff6b12fed.py
│   │   │   │   │       ├── 2025-04-21-10-18_819927b7ccfa.py
│   │   │   │   │       ├── 2025-05-04-15-02_eddcb77eb6f3.py
│   │   │   │   │       ├── 2025-05-06-13-09_7b687c555318.py
│   │   │   │   │       ├── 2025-05-12-17-49_c2f78c69e9cf.py
│   │   │   │   │       ├── 2025-05-15-00-34_fcef2c58b21c.py
│   │   │   │   │       ├── 2025-05-15-14-18_bedb5f07417b.py
│   │   │   │   │       ├── 2025-05-16-14-33_aa167915c4d6.py
│   │   │   │   │       ├── 2025-05-19-18-48_90e3eababbf0.py
│   │   │   │   │       ├── 2025-05-19-20-54_combined_commentmention.py
│   │   │   │   │       ├── 2025-06-04-10-43_7c14f776ef6b.py
│   │   │   │   │       └── 2025-06-18-17-17_9dd1be4539e0.py
│   │   │   │   ├── preset.py
│   │   │   │   ├── provider.py
│   │   │   │   ├── provider_image.py
│   │   │   │   ├── rule.py
│   │   │   │   ├── secret.py
│   │   │   │   ├── statistics.py
│   │   │   │   ├── system.py
│   │   │   │   ├── tenant.py
│   │   │   │   ├── topology.py
│   │   │   │   ├── user.py
│   │   │   │   └── workflow.py
│   │   │   ├── facet.py
│   │   │   ├── incident.py
│   │   │   ├── provider.py
│   │   │   ├── query.py
│   │   │   ├── search_alert.py
│   │   │   ├── severity_base.py
│   │   │   ├── smtp.py
│   │   │   ├── time_stamp.py
│   │   │   ├── user.py
│   │   │   ├── webhook.py
│   │   │   └── workflow.py
│   │   ├── observability.py
│   │   ├── redis_settings.py
│   │   ├── routes/
│   │   │   ├── __init__.py
│   │   │   ├── actions.py
│   │   │   ├── ai.py
│   │   │   ├── alerts.py
│   │   │   ├── auth/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── groups.py
│   │   │   │   ├── permissions.py
│   │   │   │   ├── roles.py
│   │   │   │   └── users.py
│   │   │   ├── cel.py
│   │   │   ├── dashboard.py
│   │   │   ├── deduplications.py
│   │   │   ├── extraction.py
│   │   │   ├── facets.py
│   │   │   ├── healthcheck.py
│   │   │   ├── incidents.py
│   │   │   ├── maintenance.py
│   │   │   ├── mapping.py
│   │   │   ├── metrics.py
│   │   │   ├── preset.py
│   │   │   ├── provider_images.py
│   │   │   ├── providers.py
│   │   │   ├── pusher.py
│   │   │   ├── rules.py
│   │   │   ├── settings.py
│   │   │   ├── status.py
│   │   │   ├── tags.py
│   │   │   ├── topology.py
│   │   │   ├── whoami.py
│   │   │   └── workflows.py
│   │   ├── tasks/
│   │   │   ├── __init__.py
│   │   │   ├── notification_cache.py
│   │   │   ├── process_event_task.py
│   │   │   ├── process_incident_task.py
│   │   │   ├── process_topology_task.py
│   │   │   └── process_watcher_task.py
│   │   └── utils/
│   │       ├── alert_utils.py
│   │       ├── cel_utils.py
│   │       ├── email_utils.py
│   │       ├── enrichment_helpers.py
│   │       ├── import_ee.py
│   │       ├── pagination.py
│   │       ├── pluralize.py
│   │       ├── tenant_utils.py
│   │       └── time_stamp_helpers.py
│   ├── cli/
│   │   ├── cli.py
│   │   └── click_extensions.py
│   ├── conditions/
│   │   ├── __init__.py
│   │   ├── assert_condition.py
│   │   ├── base_condition.py
│   │   ├── condition_factory.py
│   │   ├── stddev_condition.py
│   │   └── threshold_condition.py
│   ├── contextmanager/
│   │   ├── __init__.py
│   │   └── contextmanager.py
│   ├── entrypoint.sh
│   ├── event_subscriber/
│   │   ├── __init__.py
│   │   └── event_subscriber.py
│   ├── exceptions/
│   │   ├── __init__.py
│   │   ├── action_error.py
│   │   ├── provider_config_exception.py
│   │   ├── provider_connection_failed.py
│   │   └── provider_exception.py
│   ├── functions/
│   │   ├── __init__.py
│   │   └── cyaml.py
│   ├── identitymanager/
│   │   ├── authenticatedentity.py
│   │   ├── authverifierbase.py
│   │   ├── identity_managers/
│   │   │   ├── __init__.py
│   │   │   ├── db/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── db_authverifier.py
│   │   │   │   └── db_identitymanager.py
│   │   │   ├── noauth/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── noauth_authverifier.py
│   │   │   │   └── noauth_identitymanager.py
│   │   │   ├── oauth2proxy/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── oauth2proxy_authverifier.py
│   │   │   │   └── oauth2proxy_identitymanager.py
│   │   │   ├── okta/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── okta_authverifier.py
│   │   │   │   └── okta_identitymanager.py
│   │   │   └── onelogin/
│   │   │       ├── __init__.py
│   │   │       ├── onelogin_authverifier.py
│   │   │       └── onelogin_identitymanager.py
│   │   ├── identitymanager.py
│   │   ├── identitymanagerfactory.py
│   │   └── rbac.py
│   ├── iohandler/
│   │   └── iohandler.py
│   ├── parser/
│   │   └── parser.py
│   ├── providers/
│   │   ├── __init__.py
│   │   ├── airflow_provider/
│   │   │   ├── __init__.py
│   │   │   └── airflow_provider.py
│   │   ├── aks_provider/
│   │   │   └── aks_provider.py
│   │   ├── amazonsqs_provider/
│   │   │   ├── __init__.py
│   │   │   └── amazonsqs_provider.py
│   │   ├── anthropic_provider/
│   │   │   ├── __init__.py
│   │   │   └── anthropic_provider.py
│   │   ├── appdynamics_provider/
│   │   │   ├── __init__.py
│   │   │   ├── appdynamics_provider.py
│   │   │   └── httpactiontemplate.json
│   │   ├── argocd_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   ├── applicationset.yaml
│   │   │   └── argocd_provider.py
│   │   ├── asana_provider/
│   │   │   ├── __init__.py
│   │   │   └── asana_provider.py
│   │   ├── auth0_provider/
│   │   │   ├── __init__.py
│   │   │   └── auth0_provider.py
│   │   ├── axiom_provider/
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   └── axiom_provider.py
│   │   ├── azuremonitoring_provider/
│   │   │   ├── __init__.py
│   │   │   └── azuremonitoring_provider.py
│   │   ├── base/
│   │   │   ├── __init__.py
│   │   │   ├── base_provider.py
│   │   │   └── provider_exceptions.py
│   │   ├── bash_provider/
│   │   │   ├── __init__.py
│   │   │   └── bash_provider.py
│   │   ├── bigquery_provider/
│   │   │   ├── __init__.py
│   │   │   └── bigquery_provider.py
│   │   ├── centreon_provider/
│   │   │   ├── __init__.py
│   │   │   └── centreon_provider.py
│   │   ├── checkly_provider/
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   └── checkly_provider.py
│   │   ├── checkmk_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   ├── checkmk_provider.py
│   │   │   └── webhook-keep.py
│   │   ├── cilium_provider/
│   │   │   ├── __init__.py
│   │   │   ├── cilium_provider.py
│   │   │   ├── generate_protobuf.py
│   │   │   ├── grpc/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── flow/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── flow.proto
│   │   │   │   │   ├── flow_pb2.py
│   │   │   │   │   └── flow_pb2_grpc.py
│   │   │   │   ├── google/
│   │   │   │   │   └── protobuf/
│   │   │   │   │       ├── duration.proto
│   │   │   │   │       ├── timestamp.proto
│   │   │   │   │       └── wrappers.proto
│   │   │   │   ├── observer.proto
│   │   │   │   ├── observer_pb2.py
│   │   │   │   ├── observer_pb2_grpc.py
│   │   │   │   └── relay/
│   │   │   │       ├── __init__.py
│   │   │   │       ├── relay.proto
│   │   │   │       ├── relay_pb2.py
│   │   │   │       └── relay_pb2_grpc.py
│   │   │   └── runtime_version.py
│   │   ├── clickhouse_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   ├── clickhouse-secure/
│   │   │   │   ├── certs/
│   │   │   │   │   ├── server.crt
│   │   │   │   │   └── server.key
│   │   │   │   ├── config.xml
│   │   │   │   ├── docker-compose.yml
│   │   │   │   └── users.xml
│   │   │   └── clickhouse_provider.py
│   │   ├── cloudwatch_provider/
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   └── cloudwatch_provider.py
│   │   ├── console_provider/
│   │   │   ├── __init__.py
│   │   │   └── console_provider.py
│   │   ├── coralogix_provider/
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   └── coralogix_provider.py
│   │   ├── dash0_provider/
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   └── dash0_provider.py
│   │   ├── databend_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   └── databend_provider.py
│   │   ├── datadog_provider/
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   ├── datadog_alert_format_description.py
│   │   │   ├── datadog_provider.py
│   │   │   └── topology_mock.py
│   │   ├── deepseek_provider/
│   │   │   ├── __init__.py
│   │   │   └── deepseek_provider.py
│   │   ├── discord_provider/
│   │   │   ├── __init__.py
│   │   │   └── discord_provider.py
│   │   ├── dynatrace_provider/
│   │   │   ├── __init__.py
│   │   │   └── dynatrace_provider.py
│   │   ├── eks_provider/
│   │   │   └── eks_provider.py
│   │   ├── elastic_provider/
│   │   │   ├── __init__.py
│   │   │   └── elastic_provider.py
│   │   ├── flashduty_provider/
│   │   │   ├── __init__.py
│   │   │   └── flashduty_provider.py
│   │   ├── fluxcd_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   ├── example.yaml
│   │   │   ├── fluxcd_provider.py
│   │   │   ├── requirements.txt
│   │   │   ├── setup.py
│   │   │   └── test_fluxcd_provider.py
│   │   ├── gcpmonitoring_provider/
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   └── gcpmonitoring_provider.py
│   │   ├── gemini_provider/
│   │   │   ├── __init__.py
│   │   │   └── gemini_provider.py
│   │   ├── github_provider/
│   │   │   ├── __init__.py
│   │   │   └── github_provider.py
│   │   ├── github_workflows_provider/
│   │   │   ├── __init__.py
│   │   │   └── github_workflows_provider.py
│   │   ├── gitlab_provider/
│   │   │   ├── __init__.py
│   │   │   └── gitlab_provider.py
│   │   ├── gitlabpipelines_provider/
│   │   │   ├── __init__.py
│   │   │   └── gitlabpipelines_provider.py
│   │   ├── gke_provider/
│   │   │   ├── __init__.py
│   │   │   └── gke_provider.py
│   │   ├── google_chat_provider/
│   │   │   ├── __init__.py
│   │   │   └── google_chat_provider.py
│   │   ├── grafana_incident_provider/
│   │   │   ├── __init__.py
│   │   │   └── grafana_incident_provider.py
│   │   ├── grafana_loki_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   ├── docker-compose.auth.yml
│   │   │   └── grafana_loki_provider.py
│   │   ├── grafana_oncall_provider/
│   │   │   ├── __init__.py
│   │   │   └── grafana_oncall_provider.py
│   │   ├── grafana_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   ├── docker-compose.yml
│   │   │   ├── grafana/
│   │   │   │   ├── grafana.ini
│   │   │   │   └── provisioning/
│   │   │   │       ├── access_control/
│   │   │   │       │   └── custom_roles.yml
│   │   │   │       ├── alerting/
│   │   │   │       │   ├── alerts.yml
│   │   │   │       │   ├── contact_points.yml
│   │   │   │       │   └── notification_policies.yml
│   │   │   │       ├── dashboards/
│   │   │   │       │   ├── dashboards.yml
│   │   │   │       │   └── system.json
│   │   │   │       ├── datasources/
│   │   │   │       │   └── datasource.yml
│   │   │   │       ├── notifiers/
│   │   │   │       │   └── email.yml
│   │   │   │       └── service_accounts/
│   │   │   │           ├── service_accounts.yml
│   │   │   │           └── tokens.yml
│   │   │   ├── grafana_alert_format_description.py
│   │   │   ├── grafana_provider.py
│   │   │   └── prometheus/
│   │   │       └── prometheus.yml
│   │   ├── graylog_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   ├── docker-compose-v4.yml
│   │   │   ├── docker-compose.yml
│   │   │   └── graylog_provider.py
│   │   ├── grok_provider/
│   │   │   ├── __init__.py
│   │   │   └── grok_provider.py
│   │   ├── http_provider/
│   │   │   ├── __init__.py
│   │   │   └── http_provider.py
│   │   ├── icinga2_provider/
│   │   │   └── icinga2_provider.py
│   │   ├── ilert_provider/
│   │   │   ├── __init__.py
│   │   │   └── ilert_provider.py
│   │   ├── incidentio_provider/
│   │   │   ├── __init__.py
│   │   │   └── incidentio_provider.py
│   │   ├── incidentmanager_provider/
│   │   │   ├── __init__.py
│   │   │   └── incidentmanager_provider.py
│   │   ├── jira_provider/
│   │   │   ├── __init__.py
│   │   │   └── jira_provider.py
│   │   ├── jiraonprem_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   └── jiraonprem_provider.py
│   │   ├── kafka_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   ├── docker-compose-no-auth.yml
│   │   │   ├── docker-compose.yml
│   │   │   ├── kafka_provider.py
│   │   │   └── kafka_server_jaas.conf
│   │   ├── keep_provider/
│   │   │   ├── __init__.py
│   │   │   └── keep_provider.py
│   │   ├── kibana_provider/
│   │   │   ├── __init__.py
│   │   │   └── kibana_provider.py
│   │   ├── kubernetes_provider/
│   │   │   ├── __init__.py
│   │   │   └── kubernetes_provider.py
│   │   ├── libre_nms_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   └── libre_nms_provider.py
│   │   ├── linear_provider/
│   │   │   ├── __init__.py
│   │   │   └── linear_provider.py
│   │   ├── linearb_provider/
│   │   │   ├── __init__.py
│   │   │   └── linearb_provider.py
│   │   ├── litellm_provider/
│   │   │   ├── __init__.py
│   │   │   └── litellm_provider.py
│   │   ├── llamacpp_provider/
│   │   │   ├── __init__.py
│   │   │   └── llamacpp_provider.py
│   │   ├── mailgun_provider/
│   │   │   ├── __init__.py
│   │   │   └── mailgun_provider.py
│   │   ├── mattermost_provider/
│   │   │   ├── __init__.py
│   │   │   └── mattermost_provider.py
│   │   ├── microsoft-planner-provider/
│   │   │   ├── __init__.py
│   │   │   └── microsoft-planner-provider.py
│   │   ├── mock_provider/
│   │   │   ├── __init__.py
│   │   │   └── mock_provider.py
│   │   ├── models/
│   │   │   ├── __init__.py
│   │   │   ├── provider_config.py
│   │   │   └── provider_method.py
│   │   ├── monday_provider/
│   │   │   ├── __init__.py
│   │   │   └── monday_provider.py
│   │   ├── mongodb_provider/
│   │   │   ├── __init__.py
│   │   │   └── mongodb_provider.py
│   │   ├── mysql_provider/
│   │   │   ├── __init__.py
│   │   │   └── mysql_provider.py
│   │   ├── netbox_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   └── netbox_provider.py
│   │   ├── netdata_provider/
│   │   │   ├── __init__.py
│   │   │   └── netdata_provider.py
│   │   ├── netxms_provider/
│   │   │   ├── __init__.py
│   │   │   └── netxms_provider.py
│   │   ├── newrelic_provider/
│   │   │   ├── __init__.py
│   │   │   └── newrelic_provider.py
│   │   ├── ntfy_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   ├── docker-compose.yml
│   │   │   ├── ntfy_provider.py
│   │   │   └── server.yml
│   │   ├── ollama_provider/
│   │   │   ├── __init__.py
│   │   │   └── ollama_provider.py
│   │   ├── openai_provider/
│   │   │   ├── __init__.py
│   │   │   └── openai_provider.py
│   │   ├── openobserve_provider/
│   │   │   ├── __init__.py
│   │   │   ├── alerttemplate.json
│   │   │   └── openobserve_provider.py
│   │   ├── opensearchserverless_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   └── opensearchserverless_provider.py
│   │   ├── openshift_provider/
│   │   │   ├── __init__.py
│   │   │   └── openshift_provider.py
│   │   ├── opsgenie_provider/
│   │   │   ├── __init__.py
│   │   │   └── opsgenie_provider.py
│   │   ├── pagerduty_provider/
│   │   │   ├── __init__.py
│   │   │   └── pagerduty_provider.py
│   │   ├── pagertree_provider/
│   │   │   ├── __init__.py
│   │   │   └── pagertree_provider.py
│   │   ├── parseable_provider/
│   │   │   ├── __init__.py
│   │   │   └── parseable_provider.py
│   │   ├── pingdom_provider/
│   │   │   ├── __init__.py
│   │   │   └── pingdom_provider.py
│   │   ├── planner_provider/
│   │   │   ├── __init__.py
│   │   │   └── planner_provider.py
│   │   ├── postgres_provider/
│   │   │   ├── __init__.py
│   │   │   └── postgres_provider.py
│   │   ├── posthog_provider/
│   │   │   ├── __init__.py
│   │   │   └── posthog_provider.py
│   │   ├── prometheus_provider/
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   └── prometheus_provider.py
│   │   ├── providers_factory.py
│   │   ├── providers_service.py
│   │   ├── pushover_provider/
│   │   │   ├── __init__.py
│   │   │   └── pushover_provider.py
│   │   ├── python_provider/
│   │   │   ├── __init__.py
│   │   │   └── python_provider.py
│   │   ├── quickchart_provider/
│   │   │   ├── __init__.py
│   │   │   └── quickchart_provider.py
│   │   ├── redmine_provider/
│   │   │   ├── __init__.py
│   │   │   └── redmine_provider.py
│   │   ├── resend_provider/
│   │   │   ├── __init__.py
│   │   │   └── resend_provider.py
│   │   ├── rollbar_provider/
│   │   │   └── rollbar_provider.py
│   │   ├── s3_provider/
│   │   │   ├── __init__.py
│   │   │   └── s3_provider.py
│   │   ├── salesforce_provider/
│   │   │   ├── __init__.py
│   │   │   └── salesforce_provider.py
│   │   ├── sendgrid_provider/
│   │   │   ├── __init__.py
│   │   │   └── sendgrid_provider.py
│   │   ├── sentry_provider/
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   └── sentry_provider.py
│   │   ├── servicenow_provider/
│   │   │   ├── .gitignore
│   │   │   ├── __init__.py
│   │   │   └── servicenow_provider.py
│   │   ├── signalfx_provider/
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   └── signalfx_provider.py
│   │   ├── signl4_provider/
│   │   │   ├── __init__.py
│   │   │   └── signl4_provider.py
│   │   ├── site24x7_provider/
│   │   │   ├── __init__.py
│   │   │   └── site24x7_provider.py
│   │   ├── slack_provider/
│   │   │   ├── __init__.py
│   │   │   └── slack_provider.py
│   │   ├── smtp_provider/
│   │   │   ├── __init__.py
│   │   │   └── smtp_provider.py
│   │   ├── snowflake_provider/
│   │   │   ├── __init__.py
│   │   │   └── snowflake_provider.py
│   │   ├── splunk_provider/
│   │   │   ├── __init__.py
│   │   │   └── splunk_provider.py
│   │   ├── squadcast_provider/
│   │   │   ├── __init__.py
│   │   │   └── squadcast_provider.py
│   │   ├── ssh_provider/
│   │   │   ├── __init__.py
│   │   │   └── ssh_provider.py
│   │   ├── statuscake_provider/
│   │   │   ├── __init__.py
│   │   │   └── statuscake_provider.py
│   │   ├── sumologic_provider/
│   │   │   ├── __init__.py
│   │   │   ├── connection_template.json
│   │   │   └── sumologic_provider.py
│   │   ├── teams_provider/
│   │   │   ├── __init__.py
│   │   │   └── teams_provider.py
│   │   ├── telegram_provider/
│   │   │   ├── __init__.py
│   │   │   └── telegram_provider.py
│   │   ├── thousandeyes_provider/
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   └── thousandeyes_provider.py
│   │   ├── trello_provider/
│   │   │   ├── __init__.py
│   │   │   └── trello_provider.py
│   │   ├── twilio_provider/
│   │   │   └── twilio_provider.py
│   │   ├── uptimekuma_provider/
│   │   │   ├── __init__.py
│   │   │   └── uptimekuma_provider.py
│   │   ├── vectordev_provider/
│   │   │   ├── __init__.py
│   │   │   └── vectordev_provider.py
│   │   ├── victorialogs_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   └── victorialogs_provider.py
│   │   ├── victoriametrics_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   └── victoriametrics_provider.py
│   │   ├── vllm_provider/
│   │   │   ├── __init__.py
│   │   │   └── vllm_provider.py
│   │   ├── wazuh_provider/
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   ├── custom-keep
│   │   │   ├── custom-keep.py
│   │   │   └── wazuh_provider.py
│   │   ├── webhook_provider/
│   │   │   ├── __init__.py
│   │   │   └── webhook_provider.py
│   │   ├── websocket_provider/
│   │   │   ├── __init__.py
│   │   │   └── websocket_provider.py
│   │   ├── youtrack_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   └── youtrack_provider.py
│   │   ├── zabbix_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   ├── zabbix_provider.py
│   │   │   └── zabbix_provider_script.js
│   │   ├── zendesk_provider/
│   │   │   ├── __init__.py
│   │   │   └── zendesk_provider.py
│   │   ├── zenduty_provider/
│   │   │   ├── __init__.py
│   │   │   └── zenduty_provider.py
│   │   ├── zoom_chat_provider/
│   │   │   ├── __init__.py
│   │   │   └── zoom_chat_provider.py
│   │   └── zoom_provider/
│   │       ├── __init__.py
│   │       └── zoom_provider.py
│   ├── rulesengine/
│   │   ├── __init__.py
│   │   └── rulesengine.py
│   ├── searchengine/
│   │   └── searchengine.py
│   ├── secretmanager/
│   │   ├── __init__.py
│   │   ├── awssecretmanager.py
│   │   ├── dbsecretmanager.py
│   │   ├── filesecretmanager.py
│   │   ├── gcpsecretmanager.py
│   │   ├── kubernetessecretmanager.py
│   │   ├── secretmanager.py
│   │   ├── secretmanagerfactory.py
│   │   └── vaultsecretmanager.py
│   ├── server_jobs_bg.py
│   ├── step/
│   │   ├── __init__.py
│   │   ├── step.py
│   │   └── step_provider_parameter.py
│   ├── throttles/
│   │   ├── base_throttle.py
│   │   ├── one_until_resolved_throttle.py
│   │   └── throttle_factory.py
│   ├── topologies/
│   │   ├── topologies_service.py
│   │   └── topology_processor.py
│   ├── validation/
│   │   ├── __init__.py
│   │   └── fields.py
│   └── workflowmanager/
│       ├── __init__.py
│       ├── workflow.py
│       ├── workflowmanager.py
│       ├── workflowscheduler.py
│       └── workflowstore.py
├── keep-ui/
│   ├── .dockerignore
│   ├── .eslintignore
│   ├── .eslintrc.json
│   ├── .gitignore
│   ├── .prettierrc
│   ├── README.md
│   ├── __mocks__/
│   │   ├── @monaco-editor/
│   │   │   └── react.js
│   │   └── monaco-editor.js
│   ├── app/
│   │   ├── (health)/
│   │   │   ├── health/
│   │   │   │   ├── check.tsx
│   │   │   │   ├── modal.tsx
│   │   │   │   └── page.tsx
│   │   │   └── layout.tsx
│   │   ├── (keep)/
│   │   │   ├── [...not-found]/
│   │   │   │   └── page.tsx
│   │   │   ├── ai/
│   │   │   │   ├── ai-plugins.tsx
│   │   │   │   ├── model.ts
│   │   │   │   └── page.tsx
│   │   │   ├── alerts/
│   │   │   │   └── [id]/
│   │   │   │       ├── page.tsx
│   │   │   │       └── ui/
│   │   │   │           ├── __tests__/
│   │   │   │           │   └── alerts-fingerprint.test.tsx
│   │   │   │           ├── alert-table-alert-facets.tsx
│   │   │   │           ├── alert-table-facet-dynamic.tsx
│   │   │   │           ├── alert-table-facet-types.tsx
│   │   │   │           ├── alert-table-facet-utils.tsx
│   │   │   │           ├── alert-table-facet-value.tsx
│   │   │   │           ├── alert-table-facet.tsx
│   │   │   │           ├── alert-table-tab-panel-server-side.tsx
│   │   │   │           └── alerts.tsx
│   │   │   ├── dashboard/
│   │   │   │   ├── GridItem.tsx
│   │   │   │   ├── GridItemContainer.tsx
│   │   │   │   ├── GridLayout.tsx
│   │   │   │   ├── MenuButton.tsx
│   │   │   │   ├── WidgetModal.tsx
│   │   │   │   ├── [id]/
│   │   │   │   │   ├── dashboard.tsx
│   │   │   │   │   └── page.tsx
│   │   │   │   ├── alert-quality-table.tsx
│   │   │   │   ├── styles.css
│   │   │   │   ├── types.tsx
│   │   │   │   └── widget-types/
│   │   │   │       ├── generic-metrics/
│   │   │   │       │   ├── generic-metrics-grid-item.tsx
│   │   │   │       │   └── generic-metrics-widget-form.tsx
│   │   │   │       ├── metric/
│   │   │   │       │   ├── metric-grid-item.tsx
│   │   │   │       │   └── metric-widget-form.tsx
│   │   │   │       └── preset/
│   │   │   │           ├── columns-selection.tsx
│   │   │   │           ├── constants.ts
│   │   │   │           ├── preset-grid-item.tsx
│   │   │   │           ├── preset-widget-form.tsx
│   │   │   │           ├── widget-alert-count-panel.tsx
│   │   │   │           └── widget-alerts-table.tsx
│   │   │   ├── deduplication/
│   │   │   │   ├── DeduplicationPlaceholder.tsx
│   │   │   │   ├── DeduplicationSidebar.tsx
│   │   │   │   ├── DeduplicationTable.tsx
│   │   │   │   ├── client.tsx
│   │   │   │   ├── models.tsx
│   │   │   │   └── page.tsx
│   │   │   ├── error.ts
│   │   │   ├── extraction/
│   │   │   │   ├── [rule_id]/
│   │   │   │   │   └── executions/
│   │   │   │   │       ├── [execution_id]/
│   │   │   │   │       │   └── page.tsx
│   │   │   │   │       └── page.tsx
│   │   │   │   ├── create-or-update-extraction-rule.tsx
│   │   │   │   ├── extraction.tsx
│   │   │   │   ├── extractions-table.tsx
│   │   │   │   ├── layout.tsx
│   │   │   │   ├── model.ts
│   │   │   │   ├── page.tsx
│   │   │   │   └── run-extraction-modal.tsx
│   │   │   ├── incidents/
│   │   │   │   ├── [id]/
│   │   │   │   │   ├── activity/
│   │   │   │   │   │   ├── incident-activity.css
│   │   │   │   │   │   ├── incident-activity.tsx
│   │   │   │   │   │   ├── lib/
│   │   │   │   │   │   │   └── extractTaggedUsers.ts
│   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   └── ui/
│   │   │   │   │   │       ├── IncidentActivityComment.tsx
│   │   │   │   │   │       ├── IncidentActivityItem.tsx
│   │   │   │   │   │       ├── IncidentCommentInput.dynamic.tsx
│   │   │   │   │   │       ├── IncidentCommentInput.scss
│   │   │   │   │   │       └── IncidentCommentInput.tsx
│   │   │   │   │   ├── alerts/
│   │   │   │   │   │   ├── ALERT_SIDEBAR_INTEGRATION.md
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── incident-alerts-sidebar.test.tsx
│   │   │   │   │   │   │   └── incident-alerts.test.tsx
│   │   │   │   │   │   ├── incident-alert-action-tray.tsx
│   │   │   │   │   │   ├── incident-alert-actions.tsx
│   │   │   │   │   │   ├── incident-alert-table-body-skeleton.tsx
│   │   │   │   │   │   ├── incident-alerts.tsx
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   ├── chat/
│   │   │   │   │   │   ├── incident-chat.css
│   │   │   │   │   │   ├── incident-chat.tsx
│   │   │   │   │   │   └── page.client.tsx
│   │   │   │   │   ├── create-ticket-modal.tsx
│   │   │   │   │   ├── enrichments/
│   │   │   │   │   │   ├── EnrichmentEditableField.tsx
│   │   │   │   │   │   └── EnrichmentEditableForm.tsx
│   │   │   │   │   ├── getIncidentWithErrorHandling.tsx
│   │   │   │   │   ├── incident-header-skeleton.tsx
│   │   │   │   │   ├── incident-header.tsx
│   │   │   │   │   ├── incident-layout-client.tsx
│   │   │   │   │   ├── incident-overview.tsx
│   │   │   │   │   ├── incident-tabs-navigation.tsx
│   │   │   │   │   ├── layout.tsx
│   │   │   │   │   ├── link-ticket-modal.tsx
│   │   │   │   │   ├── not-found.tsx
│   │   │   │   │   ├── route.tsx
│   │   │   │   │   ├── ticketing-incident-options.tsx
│   │   │   │   │   ├── timeline/
│   │   │   │   │   │   ├── incident-timeline.tsx
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   ├── topology/
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   └── workflows/
│   │   │   │   │       ├── incident-workflow-empty.tsx
│   │   │   │   │       ├── incident-workflow-sidebar.tsx
│   │   │   │   │       ├── incident-workflow-table.tsx
│   │   │   │   │       └── page.tsx
│   │   │   │   ├── incident-overview-skeleton.tsx
│   │   │   │   ├── layout.tsx
│   │   │   │   ├── page.tsx
│   │   │   │   └── predicted-incidents-table.tsx
│   │   │   ├── layout.tsx
│   │   │   ├── loading.tsx
│   │   │   ├── maintenance/
│   │   │   │   ├── create-or-update-maintenance-rule.tsx
│   │   │   │   ├── layout.tsx
│   │   │   │   ├── maintenance-rules-table.tsx
│   │   │   │   ├── maintenance.tsx
│   │   │   │   ├── model.ts
│   │   │   │   └── page.tsx
│   │   │   ├── mapping/
│   │   │   │   ├── [rule_id]/
│   │   │   │   │   └── executions/
│   │   │   │   │       ├── [execution_id]/
│   │   │   │   │       │   └── page.tsx
│   │   │   │   │       └── page.tsx
│   │   │   │   ├── create-or-edit-mapping.tsx
│   │   │   │   ├── layout.tsx
│   │   │   │   ├── mapping.tsx
│   │   │   │   ├── models.tsx
│   │   │   │   ├── page.tsx
│   │   │   │   ├── rules-table.tsx
│   │   │   │   └── run-mapping-modal.tsx
│   │   │   ├── not-found.tsx
│   │   │   ├── notifications-hub/
│   │   │   │   ├── layout.tsx
│   │   │   │   └── page.tsx
│   │   │   ├── page.tsx
│   │   │   ├── providers/
│   │   │   │   ├── components/
│   │   │   │   │   ├── providers-categories/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── providers-categories.tsx
│   │   │   │   │   ├── providers-filter-by-label/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── providers-filter-by-label.tsx
│   │   │   │   │   └── providers-search/
│   │   │   │   │       ├── index.ts
│   │   │   │   │       └── providers-search.tsx
│   │   │   │   ├── filter-context/
│   │   │   │   │   ├── constants.ts
│   │   │   │   │   ├── filter-context.tsx
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── types.ts
│   │   │   │   │   └── use-filter-context.ts
│   │   │   │   ├── form-fields.tsx
│   │   │   │   ├── form-validation.ts
│   │   │   │   ├── layout.tsx
│   │   │   │   ├── oauth2/
│   │   │   │   │   └── [providerType]/
│   │   │   │   │       └── page.tsx
│   │   │   │   ├── page.client.tsx
│   │   │   │   ├── page.tsx
│   │   │   │   ├── provider-form-scopes.css
│   │   │   │   ├── provider-form-scopes.tsx
│   │   │   │   ├── provider-form.css
│   │   │   │   ├── provider-form.tsx
│   │   │   │   ├── provider-logs.tsx
│   │   │   │   ├── provider-semi-automated.tsx
│   │   │   │   ├── provider-tile.css
│   │   │   │   ├── provider-tile.tsx
│   │   │   │   ├── providers-tiles.tsx
│   │   │   │   └── providers.css
│   │   │   ├── rules/
│   │   │   │   ├── CorrelationPlaceholder.tsx
│   │   │   │   ├── CorrelationSidebar/
│   │   │   │   │   ├── AlertsFoundBadge.tsx
│   │   │   │   │   ├── CorrelationForm.tsx
│   │   │   │   │   ├── CorrelationGroups.tsx
│   │   │   │   │   ├── CorrelationSidebarBody.tsx
│   │   │   │   │   ├── CorrelationSidebarHeader.tsx
│   │   │   │   │   ├── CorrelationSubmission.tsx
│   │   │   │   │   ├── DeleteRule.tsx
│   │   │   │   │   ├── RuleFields.tsx
│   │   │   │   │   ├── RuleGroup.tsx
│   │   │   │   │   ├── convert-cel-ast-to-query-builder-ast/
│   │   │   │   │   │   ├── convert-cel-ast-to-query-builder-ast.function.test.ts
│   │   │   │   │   │   └── convert-cel-ast-to-query-builder-ast.function.ts
│   │   │   │   │   ├── index.tsx
│   │   │   │   │   ├── timeframe-constants.ts
│   │   │   │   │   ├── types.ts
│   │   │   │   │   └── useMatchingAlerts.ts
│   │   │   │   ├── CorrelationTable.tsx
│   │   │   │   ├── GroupedByCel.tsx
│   │   │   │   ├── client.tsx
│   │   │   │   ├── flatten-cel-ast.ts
│   │   │   │   ├── page.tsx
│   │   │   │   └── ui/
│   │   │   │       └── PlaceholderSankey.tsx
│   │   │   ├── settings/
│   │   │   │   ├── auth/
│   │   │   │   │   ├── api-key-settings.tsx
│   │   │   │   │   ├── api-key-tab.tsx
│   │   │   │   │   ├── api-key-table.tsx
│   │   │   │   │   ├── groups-sidebar.tsx
│   │   │   │   │   ├── groups-tab.tsx
│   │   │   │   │   ├── groups-table.tsx
│   │   │   │   │   ├── multiselect.css
│   │   │   │   │   ├── permissions-sidebar.tsx
│   │   │   │   │   ├── permissions-tab.tsx
│   │   │   │   │   ├── permissions-table.tsx
│   │   │   │   │   ├── roles-sidebar.tsx
│   │   │   │   │   ├── roles-tab.tsx
│   │   │   │   │   ├── roles-table.tsx
│   │   │   │   │   ├── sso-settings.tsx
│   │   │   │   │   ├── sso-tab.tsx
│   │   │   │   │   ├── types.ts
│   │   │   │   │   ├── users-settings.tsx
│   │   │   │   │   ├── users-sidebar.tsx
│   │   │   │   │   ├── users-tab.tsx
│   │   │   │   │   └── users-table.tsx
│   │   │   │   ├── create-api-key-modal.tsx
│   │   │   │   ├── layout.tsx
│   │   │   │   ├── models.tsx
│   │   │   │   ├── page.tsx
│   │   │   │   ├── provider-images/
│   │   │   │   │   ├── page.tsx
│   │   │   │   │   ├── provider-image-list.tsx
│   │   │   │   │   ├── provider-image-uploader.tsx
│   │   │   │   │   └── provider-images-settings.tsx
│   │   │   │   ├── settings.client.tsx
│   │   │   │   ├── smtp-settings.tsx
│   │   │   │   └── webhook-settings.tsx
│   │   │   ├── topology/
│   │   │   │   ├── TopologySearchContext.tsx
│   │   │   │   ├── api/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── layout.tsx
│   │   │   │   ├── lib/
│   │   │   │   │   └── badge-colors.ts
│   │   │   │   ├── model/
│   │   │   │   │   ├── TopologyPollingContext.tsx
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── models.ts
│   │   │   │   │   ├── useTopology.ts
│   │   │   │   │   └── useTopologyApplications.ts
│   │   │   │   ├── page.tsx
│   │   │   │   ├── topology-client.tsx
│   │   │   │   └── ui/
│   │   │   │       ├── TopologySearchAutocomplete.tsx
│   │   │   │       ├── applications/
│   │   │   │       │   ├── application-card.tsx
│   │   │   │       │   ├── application-modal.tsx
│   │   │   │       │   ├── applications-list.tsx
│   │   │   │       │   └── create-or-update-application-form.tsx
│   │   │   │       └── map/
│   │   │   │           ├── AddEditNodeSidePanel.tsx
│   │   │   │           ├── application-node.tsx
│   │   │   │           ├── getLayoutedElements.ts
│   │   │   │           ├── getNodesAndEdgesFromTopologyData.ts
│   │   │   │           ├── index.tsx
│   │   │   │           ├── manage-selection.tsx
│   │   │   │           ├── service-node.tsx
│   │   │   │           ├── styles.tsx
│   │   │   │           ├── topology-map.tsx
│   │   │   │           └── topology.css
│   │   │   └── workflows/
│   │   │       ├── [workflow_id]/
│   │   │       │   ├── layout.tsx
│   │   │       │   ├── page.tsx
│   │   │       │   ├── runs/
│   │   │       │   │   └── [workflow_execution_id]/
│   │   │       │   │       └── page.tsx
│   │   │       │   ├── table-filters.tsx
│   │   │       │   ├── versions/
│   │   │       │   │   └── [revision]/
│   │   │       │   │       └── page.tsx
│   │   │       │   ├── workflow-breadcrumbs.tsx
│   │   │       │   ├── workflow-detail-header.tsx
│   │   │       │   ├── workflow-detail-page.tsx
│   │   │       │   ├── workflow-executions-table.tsx
│   │   │       │   ├── workflow-overview-skeleton.tsx
│   │   │       │   ├── workflow-overview.tsx
│   │   │       │   ├── workflow-providers.tsx
│   │   │       │   ├── workflow-secrets.tsx
│   │   │       │   ├── workflow-sync-status.tsx
│   │   │       │   └── workflow-versions.tsx
│   │   │       ├── __tests__/
│   │   │       │   └── existing-workflows-state.test.tsx
│   │   │       ├── builder/
│   │   │       │   ├── [workflowId]/
│   │   │       │   │   └── page.tsx
│   │   │       │   ├── layout.tsx
│   │   │       │   └── page.tsx
│   │   │       ├── create-workflow-modal.tsx
│   │   │       ├── existing-workflows-state.tsx
│   │   │       ├── no-workflows-state.tsx
│   │   │       ├── noworkflows.tsx
│   │   │       ├── page.tsx
│   │   │       ├── preview/
│   │   │       │   ├── [workflowId]/
│   │   │       │   │   └── page.tsx
│   │   │       │   └── page.tsx
│   │   │       ├── upload-workflows-modal.tsx
│   │   │       ├── workflow-graph.tsx
│   │   │       ├── workflow-menu.tsx
│   │   │       ├── workflow-templates/
│   │   │       │   ├── index.ts
│   │   │       │   ├── workflow-template-card.tsx
│   │   │       │   └── workflow-templates.tsx
│   │   │       ├── workflow-tile.css
│   │   │       ├── workflow-tile.tsx
│   │   │       ├── workflow-utils.ts
│   │   │       ├── workflows-steps.tsx
│   │   │       └── workflows.page.tsx
│   │   ├── (signin)/
│   │   │   ├── error/
│   │   │   │   ├── authEnvUtils.tsx
│   │   │   │   ├── error-client.tsx
│   │   │   │   └── page.tsx
│   │   │   ├── layout.tsx
│   │   │   ├── mobile/
│   │   │   │   ├── GithubButton.tsx
│   │   │   │   └── page.tsx
│   │   │   └── signin/
│   │   │       ├── SignInForm.tsx
│   │   │       └── page.tsx
│   │   ├── actions/
│   │   │   └── authactions.ts
│   │   ├── api/
│   │   │   ├── auth/
│   │   │   │   └── [...nextauth]/
│   │   │   │       └── route.ts
│   │   │   ├── aws-marketplace/
│   │   │   │   └── route.ts
│   │   │   ├── copilotkit/
│   │   │   │   └── route.ts
│   │   │   └── healthcheck/
│   │   │       └── route.ts
│   │   ├── auth-provider.tsx
│   │   ├── config-provider.tsx
│   │   ├── global-error.tsx
│   │   ├── globals.css
│   │   ├── not-authorized.tsx
│   │   ├── posthog-provider.tsx
│   │   └── raw/
│   │       └── workflows/
│   │           └── [workflow_filename]/
│   │               └── route.ts
│   ├── auth.config.ts
│   ├── auth.ts
│   ├── components/
│   │   ├── LinkWithIcon.tsx
│   │   ├── LogViewer.tsx
│   │   ├── SidePanel.tsx
│   │   ├── banners/
│   │   │   ├── BannerBase.tsx
│   │   │   ├── health-page-banner.tsx
│   │   │   └── read-only-banner.tsx
│   │   ├── filters/
│   │   │   └── GenericFilters.tsx
│   │   ├── icons/
│   │   │   └── index.tsx
│   │   ├── navbar/
│   │   │   ├── AILink.tsx
│   │   │   ├── AlertsLinks.tsx
│   │   │   ├── DashboardLink.tsx
│   │   │   ├── DashboardLinks.tsx
│   │   │   ├── IncidentLinks.tsx
│   │   │   ├── Menu.tsx
│   │   │   ├── MinimizeMenuButton.tsx
│   │   │   ├── Navbar.css
│   │   │   ├── Navbar.tsx
│   │   │   ├── NoiseReductionLinks.tsx
│   │   │   ├── Search.tsx
│   │   │   ├── SetSentryUser.tsx
│   │   │   ├── UserAvatar.tsx
│   │   │   └── UserInfo.tsx
│   │   ├── popover/
│   │   │   └── GenericPopover.tsx
│   │   ├── table/
│   │   │   ├── ExecutionsTable.tsx
│   │   │   ├── GenericTable.tsx
│   │   │   └── Pagination.tsx
│   │   └── ui/
│   │       ├── AutocompleteInput.tsx
│   │       ├── Button.tsx
│   │       ├── Calendar.scss
│   │       ├── Calendar.tsx
│   │       ├── CreatableMultiSelect.tsx
│   │       ├── DateRangePicker.tsx
│   │       ├── DateRangePickerV2.tsx
│   │       ├── DynamicProviderIcon.tsx
│   │       ├── EmptyStateImage.tsx
│   │       ├── EmptyStateTable.tsx
│   │       ├── ImagePreviewTooltip.tsx
│   │       ├── Link.tsx
│   │       ├── Modal.tsx
│   │       ├── ResizableColumns.tsx
│   │       ├── RootCauseAnalysis.tsx
│   │       ├── ShortNumber.tsx
│   │       ├── TextInput.tsx
│   │       ├── Textarea.tsx
│   │       ├── index.ts
│   │       └── useTimeframeState.ts
│   ├── docs/
│   │   └── incident-alerts/
│   │       ├── ALERT_SIDEBAR_INTEGRATION.md
│   │       └── CI_CD_FIXES.md
│   ├── entities/
│   │   ├── alerts/
│   │   │   ├── lib/
│   │   │   │   └── getTabsFromPreset.ts
│   │   │   ├── model/
│   │   │   │   ├── constants.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── types.ts
│   │   │   │   ├── useAlertRowStyle.ts
│   │   │   │   ├── useAlertTableTheme.ts
│   │   │   │   ├── useAlerts.ts
│   │   │   │   ├── useAvailableAlertFields.ts
│   │   │   │   └── useSeverityMapping.ts
│   │   │   └── ui/
│   │   │       ├── AlertImage/
│   │   │       │   └── AlertImage.tsx
│   │   │       ├── AlertName/
│   │   │       │   └── AlertName.tsx
│   │   │       ├── alert-severity.tsx
│   │   │       └── index.ts
│   │   ├── incidents/
│   │   │   ├── api/
│   │   │   │   ├── incidents.ts
│   │   │   │   └── index.ts
│   │   │   ├── lib/
│   │   │   │   ├── __tests__/
│   │   │   │   │   └── ticketing-utils.test.ts
│   │   │   │   ├── ticketing-utils.ts
│   │   │   │   └── utils.ts
│   │   │   ├── model/
│   │   │   │   ├── index.ts
│   │   │   │   ├── models.ts
│   │   │   │   └── useIncidentActions.tsx
│   │   │   └── ui/
│   │   │       ├── IncidentIconName/
│   │   │       │   ├── IncidentIconName.tsx
│   │   │       │   └── index.ts
│   │   │       ├── IncidentSeverityBadge.tsx
│   │   │       ├── index.ts
│   │   │       └── statuses.tsx
│   │   ├── presets/
│   │   │   └── model/
│   │   │       ├── constants.ts
│   │   │       ├── index.ts
│   │   │       ├── types.ts
│   │   │       ├── usePresetActions.ts
│   │   │       ├── usePresetColumnConfig.ts
│   │   │       ├── usePresetColumnState.ts
│   │   │       ├── usePresetPolling.ts
│   │   │       ├── usePresets.ts
│   │   │       └── useSilencedPresets.ts
│   │   ├── provider-images/
│   │   │   └── model/
│   │   │       └── useProviderImages.ts
│   │   ├── providers/
│   │   │   └── model/
│   │   │       └── __mocks__/
│   │   │           └── provider-mocks.ts
│   │   ├── users/
│   │   │   ├── model/
│   │   │   │   ├── useUser.ts
│   │   │   │   └── useUsers.ts
│   │   │   └── ui/
│   │   │       ├── UserStatefulAvatar.tsx
│   │   │       └── index.ts
│   │   ├── workflow-executions/
│   │   │   └── model/
│   │   │       ├── __tests__/
│   │   │       │   └── useWorkflowExecutionsV2.test.tsx
│   │   │       ├── index.ts
│   │   │       ├── useWorkflowExecutionDetail.ts
│   │   │       ├── useWorkflowExecutions.ts
│   │   │       ├── useWorkflowExecutionsRevalidation.ts
│   │   │       ├── useWorkflowExecutionsV2.ts
│   │   │       └── workflowExecutionsKeys.ts
│   │   └── workflows/
│   │       ├── index.ts
│   │       ├── lib/
│   │       │   ├── __tests__/
│   │       │   │   ├── extractWorkflowYamlDependencies.test.ts
│   │       │   │   ├── getCurrentPath.test.ts
│   │       │   │   ├── mustache.test.ts
│   │       │   │   ├── parseWorkflowYamlToJSON.test.ts
│   │       │   │   ├── parser.test.ts
│   │       │   │   ├── validate-mustache-ui-builder.test.ts
│   │       │   │   ├── validate-mustache-yaml.test.ts
│   │       │   │   ├── validation.test.ts
│   │       │   │   └── yaml-utils.test.ts
│   │       │   ├── extractWorkflowYamlDependencies.ts
│   │       │   ├── generateWorkflowYamlJsonSchema.ts
│   │       │   ├── getHumanReadableInterval.ts
│   │       │   ├── getLayoutedWorkflowElements.ts
│   │       │   ├── getTriggerDescription.ts
│   │       │   ├── mustache.ts
│   │       │   ├── parser.ts
│   │       │   ├── ui-utils.tsx
│   │       │   ├── use-query-workflow-template.ts
│   │       │   ├── useWorkflowJsonSchema.ts
│   │       │   ├── useWorkflowZodSchema.ts
│   │       │   ├── validate-definition.ts
│   │       │   ├── validate-mustache-ui-builder.ts
│   │       │   ├── validate-mustache-yaml.ts
│   │       │   └── yaml-utils.ts
│   │       ├── model/
│   │       │   ├── __mocks__/
│   │       │   │   └── mock-workflow.ts
│   │       │   ├── __tests__/
│   │       │   │   ├── types.test.ts
│   │       │   │   ├── useWorkflowActions.test.ts
│   │       │   │   ├── useWorkflowRevalidation.test.tsx
│   │       │   │   ├── useWorkflowsV2.test.ts
│   │       │   │   ├── workflow-store.test.tsx
│   │       │   │   └── yaml.schema.test.ts
│   │       │   ├── index.ts
│   │       │   ├── schema.ts
│   │       │   ├── types.ts
│   │       │   ├── useWorkflowActions.ts
│   │       │   ├── useWorkflowDetail.ts
│   │       │   ├── useWorkflowRevalidation.ts
│   │       │   ├── useWorkflowRevisions.ts
│   │       │   ├── useWorkflows.ts
│   │       │   ├── useWorkflowsV2.ts
│   │       │   ├── workflow-store.ts
│   │       │   ├── workflow-yaml-editor-store.ts
│   │       │   ├── workflowKeys.ts
│   │       │   ├── yaml.schema.ts
│   │       │   └── yaml.types.ts
│   │       └── ui/
│   │           ├── NodeTriggerIcon.tsx
│   │           ├── TriggerIcon.tsx
│   │           ├── WorkflowAlertIncidentDependenciesForm.tsx
│   │           ├── WorkflowInputFields.tsx
│   │           ├── WorkflowPermissionsBadge.tsx
│   │           └── WorkflowTriggerBadge.tsx
│   ├── entrypoint.sh
│   ├── errors.ts
│   ├── eslint.config.mjs
│   ├── features/
│   │   ├── alerts/
│   │   │   ├── alert-assign-ticket/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       └── alert-assign-ticket-modal.tsx
│   │   │   ├── alert-associate-to-incident/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       └── alert-associate-incident-modal.tsx
│   │   │   ├── alert-call-provider-method/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       ├── alert-method-modal.tsx
│   │   │   │       └── alert-method-results-table.tsx
│   │   │   ├── alert-change-status/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       └── alert-change-status-modal.tsx
│   │   │   ├── alert-create-incident-ai/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       ├── alert-create-incident-ai-card.tsx
│   │   │   │       └── alert-create-incident-ai-modal.tsx
│   │   │   ├── alert-detail-sidebar/
│   │   │   │   ├── index.ts
│   │   │   │   ├── lib/
│   │   │   │   │   └── alertSidebarFields.tsx
│   │   │   │   └── ui/
│   │   │   │       ├── alert-sidebar-incidents.tsx
│   │   │   │       ├── alert-sidebar.tsx
│   │   │   │       └── alert-timeline.tsx
│   │   │   ├── alert-error-event-process/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       └── alert-error-event-modal.tsx
│   │   │   ├── alert-history/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       ├── alert-history-charts.tsx
│   │   │   │       └── alert-history-modal.tsx
│   │   │   ├── alert-menu/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       └── alert-menu.tsx
│   │   │   ├── alert-note/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       └── alert-note-modal.tsx
│   │   │   ├── change-alert-table-theme/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       ├── AlertTableThemeSelection.tsx
│   │   │   │       └── __tests__/
│   │   │   │           └── change-alert-table-theme.test.tsx
│   │   │   ├── dismiss-alert/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       ├── alert-dismiss-modal.css
│   │   │   │       └── alert-dismiss-modal.tsx
│   │   │   ├── enrich-alert/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       └── EnrichAlertSidePanel.tsx
│   │   │   ├── severity-mapping/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       ├── SeverityMappingFacet.tsx
│   │   │   │       └── SeverityMappingSelection.tsx
│   │   │   ├── simulate-alert/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       └── alert-push-alert-to-server-modal.tsx
│   │   │   └── view-raw-alert/
│   │   │       ├── index.ts
│   │   │       └── ui/
│   │   │           ├── ViewAlertModal.css
│   │   │           └── ViewAlertModal.tsx
│   │   ├── cel-input/
│   │   │   ├── __tests__/
│   │   │   │   └── use-cel-state.test.ts
│   │   │   ├── cel-input.tsx
│   │   │   └── use-cel-state.ts
│   │   ├── filter/
│   │   │   ├── add-facet-modal-with-suggestions.tsx
│   │   │   ├── add-facet-modal.tsx
│   │   │   ├── api.ts
│   │   │   ├── facet-panel-server-side.tsx
│   │   │   ├── facet-value.tsx
│   │   │   ├── facet.tsx
│   │   │   ├── facets-panel.tsx
│   │   │   ├── hooks.tsx
│   │   │   ├── index.ts
│   │   │   ├── models.tsx
│   │   │   ├── pagination.tsx
│   │   │   ├── search-input.tsx
│   │   │   └── store/
│   │   │       ├── __tests__/
│   │   │       │   ├── facets-store.test.ts
│   │   │       │   ├── use-initial-state-handler.test.ts
│   │   │       │   ├── use-queries-handler.test.ts
│   │   │       │   └── utils.test.ts
│   │   │       ├── create-facets-store.ts
│   │   │       ├── index.ts
│   │   │       ├── use-facets-config.tsx
│   │   │       ├── use-facets-loading-state-handler.ts
│   │   │       ├── use-initial-state-handler.ts
│   │   │       ├── use-queries-handler.ts
│   │   │       ├── use-query-params/
│   │   │       │   ├── __tests__/
│   │   │       │   │   ├── split-facet-values.test.ts
│   │   │       │   │   └── use-query-params.test.ts
│   │   │       │   ├── split-facet-values.ts
│   │   │       │   └── use-query-params.ts
│   │   │       ├── use-store.tsx
│   │   │       └── utils.ts
│   │   ├── incidents/
│   │   │   ├── change-incident-severity/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       ├── incident-change-severity-select.tsx
│   │   │   │       └── incident-severity-select.tsx
│   │   │   ├── change-incident-status/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       └── incident-change-status-select.tsx
│   │   │   ├── create-or-update-incident/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       ├── create-or-update-incident-form.tsx
│   │   │   │       └── react-quill-override.css
│   │   │   ├── incident-list/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       ├── incident-dropdown-menu.tsx
│   │   │   │       ├── incident-list-error.tsx
│   │   │   │       ├── incident-list-placeholder.tsx
│   │   │   │       ├── incident-list.tsx
│   │   │   │       ├── incident-table-component.tsx
│   │   │   │       ├── incident-table-filters-context.tsx
│   │   │   │       ├── incidents-not-found.tsx
│   │   │   │       ├── incidents-report/
│   │   │   │       │   ├── generate-report-modal.tsx
│   │   │   │       │   ├── incident-severity-metric.tsx
│   │   │   │       │   ├── incidents-report.tsx
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── models.ts
│   │   │   │       │   ├── pie-chart.tsx
│   │   │   │       │   └── use-report-data.ts
│   │   │   │       ├── incidents-table.tsx
│   │   │   │       └── useIncidentsTableData.tsx
│   │   │   ├── merge-incidents/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       └── merge-incidents-modal.tsx
│   │   │   ├── same-incidents-in-the-past/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       ├── change-same-incident-in-the-past-form.tsx
│   │   │   │       ├── following-incidents.tsx
│   │   │   │       ├── index.ts
│   │   │   │       └── same-incident-field.tsx
│   │   │   └── split-incident-alerts/
│   │   │       ├── index.ts
│   │   │       └── ui/
│   │   │           └── split-incident-alerts-modal.tsx
│   │   ├── keyboard-shortcuts/
│   │   │   ├── index.ts
│   │   │   └── useIsShiftKeyHeld.ts
│   │   ├── presets/
│   │   │   ├── create-or-update-preset/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       ├── alerts-count-badge.tsx
│   │   │   │       ├── create-or-update-preset-form.tsx
│   │   │   │       └── preset-controls.tsx
│   │   │   ├── custom-preset-links/
│   │   │   │   ├── index.ts
│   │   │   │   ├── model/
│   │   │   │   │   └── usePresetAlertsCount.ts
│   │   │   │   └── ui/
│   │   │   │       ├── CustomPresetAlertLink.css
│   │   │   │       ├── CustomPresetAlertLinks.tsx
│   │   │   │       └── PresetsNoise.tsx
│   │   │   └── presets-manager/
│   │   │       ├── index.ts
│   │   │       ├── lib/
│   │   │       │   └── eval-with-context.ts
│   │   │       └── ui/
│   │   │           ├── __tests__/
│   │   │           │   ├── alert-preset-manager.test.tsx
│   │   │           │   └── preset-navigation.test.ts
│   │   │           ├── alert-preset-manager.tsx
│   │   │           └── alerts-rules-builder.tsx
│   │   ├── workflow-execution-results/
│   │   │   ├── index.ts
│   │   │   ├── lib/
│   │   │   │   └── logs-utils.ts
│   │   │   └── ui/
│   │   │       ├── WorkflowExecutionError.tsx
│   │   │       ├── WorkflowExecutionLogs.tsx
│   │   │       └── WorkflowExecutionResults.tsx
│   │   └── workflows/
│   │       ├── ai-assistant/
│   │       │   ├── index.ts
│   │       │   ├── lib/
│   │       │   │   ├── constants.ts
│   │       │   │   └── utils.ts
│   │       │   └── ui/
│   │       │       ├── AddStepUI.tsx
│   │       │       ├── AddTriggerOrStepSkeleton.tsx
│   │       │       ├── AddTriggerUI.tsx
│   │       │       ├── StepPreview.tsx
│   │       │       ├── SuggestionStatus.tsx
│   │       │       ├── WorkflowBuilderChat.tsx
│   │       │       ├── WorkflowBuilderChatSafe.tsx
│   │       │       └── chat.css
│   │       ├── builder/
│   │       │   ├── index.ts
│   │       │   ├── lib/
│   │       │   │   └── utils.tsx
│   │       │   └── ui/
│   │       │       ├── Editor/
│   │       │       │   ├── EditorField.tsx
│   │       │       │   ├── ReactFlowEditor.tsx
│   │       │       │   ├── StepEditor.tsx
│   │       │       │   ├── StepTest.tsx
│   │       │       │   ├── TriggerEditor.tsx
│   │       │       │   └── WorkflowEditor.tsx
│   │       │       ├── NodeMenu.tsx
│   │       │       ├── ReactFlowBuilder.tsx
│   │       │       ├── WorkflowEdge.tsx
│   │       │       ├── WorkflowNode.tsx
│   │       │       ├── WorkflowToolbox.tsx
│   │       │       ├── __tests__/
│   │       │       │   └── ReactFlowBuilder.test.tsx
│   │       │       └── workflow-status.tsx
│   │       ├── edit-metadata/
│   │       │   ├── index.ts
│   │       │   └── ui/
│   │       │       ├── edit-workflow-metadata-form.tsx
│   │       │       └── workflow-metadata-modal.tsx
│   │       ├── edit-workflow-metadata/
│   │       │   ├── index.ts
│   │       │   └── ui/
│   │       │       └── edit-workflow-metadata-form.tsx
│   │       ├── enable-disable/
│   │       │   ├── index.ts
│   │       │   ├── model/
│   │       │   │   ├── index.ts
│   │       │   │   └── useWorkflowToggle.ts
│   │       │   └── ui/
│   │       │       └── WorkflowEnabledSwitch.tsx
│   │       ├── manual-run-workflow/
│   │       │   ├── index.ts
│   │       │   ├── model/
│   │       │   │   ├── WorkflowModalContext.tsx
│   │       │   │   ├── types.ts
│   │       │   │   └── useWorkflowRun.ts
│   │       │   └── ui/
│   │       │       ├── WorkflowInputsForm.tsx
│   │       │       ├── WorkflowUnsavedChangesForm.tsx
│   │       │       ├── manual-run-workflow-modal.tsx
│   │       │       └── workflow-run-with-alert-modal.tsx
│   │       └── test-run/
│   │           ├── index.ts
│   │           ├── model/
│   │           │   └── useWorkflowTestRun.ts
│   │           └── ui/
│   │               └── workflow-test-run-button.tsx
│   ├── instrumentation.ts
│   ├── jest.config.ts
│   ├── jest.setup.ts
│   ├── middleware.ts
│   ├── next-env.d.ts
│   ├── next.config.js
│   ├── next_build.sh
│   ├── next_start.sh
│   ├── package.json
│   ├── postcss.config.js
│   ├── proxyFetch.node.ts
│   ├── proxyFetch.ts
│   ├── scripts/
│   │   ├── build-monaco-workers-turbopack.js
│   │   ├── generate-workflow-yaml-json-schema.ts
│   │   └── validate-workflow-examples.ts
│   ├── sentry.client.config.ts
│   ├── sentry.edge.config.ts
│   ├── sentry.server.config.ts
│   ├── shared/
│   │   ├── api/
│   │   │   ├── ApiClient.ts
│   │   │   ├── KeepApiError.ts
│   │   │   ├── __tests__/
│   │   │   │   └── ApiClient.test.ts
│   │   │   ├── enrichment-events.ts
│   │   │   ├── index.ts
│   │   │   ├── providers.ts
│   │   │   ├── server/
│   │   │   │   ├── createServerApiClient.ts
│   │   │   │   └── index.ts
│   │   │   ├── workflow-executions.ts
│   │   │   └── workflows.ts
│   │   ├── constants.ts
│   │   ├── lib/
│   │   │   ├── __tests__/
│   │   │   │   ├── getIconForStatusString.test.tsx
│   │   │   │   ├── logs-utils.test.ts
│   │   │   │   ├── oauth2proxy-auth.test.ts
│   │   │   │   ├── object-utils.test.ts
│   │   │   │   ├── provider-utils.test.ts
│   │   │   │   ├── regex-utils.test.ts
│   │   │   │   ├── severity-utils.test.ts
│   │   │   │   └── status-utils.test.ts
│   │   │   ├── capture.ts
│   │   │   ├── downloadFileFromString.ts
│   │   │   ├── encodings.ts
│   │   │   ├── getApiUrlFromConfig.ts
│   │   │   ├── hooks/
│   │   │   │   ├── __tests__/
│   │   │   │   │   └── useSignOut.test.ts
│   │   │   │   ├── useApi.tsx
│   │   │   │   ├── useHealth.ts
│   │   │   │   ├── useHydratedSession.tsx
│   │   │   │   ├── useMounted.tsx
│   │   │   │   ├── useSetSentryUser.ts
│   │   │   │   └── useSignOut.ts
│   │   │   ├── logs-utils.ts
│   │   │   ├── oauth2proxy-auth.ts
│   │   │   ├── object-utils.ts
│   │   │   ├── provider-utils.ts
│   │   │   ├── regex-utils.ts
│   │   │   ├── server/
│   │   │   │   └── getConfig.ts
│   │   │   ├── state-utils.ts
│   │   │   ├── status-utils.ts
│   │   │   └── tremor-utils.ts
│   │   ├── tests/
│   │   │   └── next-auth-mock.tsx
│   │   └── ui/
│   │       ├── DateTimeField.tsx
│   │       ├── DebugJSON/
│   │       │   ├── DebugJSON.tsx
│   │       │   └── index.ts
│   │       ├── Drawer/
│   │       │   ├── Drawer.tsx
│   │       │   ├── TremorDrawer.tsx
│   │       │   └── index.ts
│   │       ├── DropdownMenu/
│   │       │   ├── DropdownMenu.css
│   │       │   ├── DropdownMenu.tsx
│   │       │   └── index.ts
│   │       ├── EmptyState/
│   │       │   ├── EmptyStateCard.tsx
│   │       │   └── index.ts
│   │       ├── ErrorComponent/
│   │       │   ├── ErrorComponent.tsx
│   │       │   └── index.ts
│   │       ├── FieldHeader.tsx
│   │       ├── FormattedContent/
│   │       │   └── FormattedContent.tsx
│   │       ├── Input/
│   │       │   └── index.tsx
│   │       ├── JsonCard/
│   │       │   ├── JsonCard.tsx
│   │       │   └── index.ts
│   │       ├── KeepLoader/
│   │       │   └── KeepLoader.tsx
│   │       ├── KeepLogoError/
│   │       │   ├── KeepLogoError.tsx
│   │       │   ├── index.ts
│   │       │   └── logo-error.css
│   │       ├── MarkdownHTML/
│   │       │   ├── MarkdownHTML.tsx
│   │       │   └── index.ts
│   │       ├── MonacoCELEditor/
│   │       │   ├── MonacoCel.tsx
│   │       │   ├── MonacoCel.turbopack.tsx
│   │       │   ├── cel-support.ts
│   │       │   ├── editor.scss
│   │       │   ├── handle-completions.ts
│   │       │   ├── index.ts
│   │       │   ├── monaco-cel-editor.tsx
│   │       │   └── validation-hook.ts
│   │       ├── MonacoEditor/
│   │       │   ├── MonacoEditorCDN.tsx
│   │       │   ├── MonacoEditorNPM.tsx
│   │       │   ├── index.ts
│   │       │   └── index.turbopack.ts
│   │       ├── MonacoYAMLEditor/
│   │       │   ├── MonacoYAMLEditor.types.ts
│   │       │   ├── editor.client.tsx
│   │       │   ├── editor.client.turbopack.tsx
│   │       │   ├── index.ts
│   │       │   └── index.turbopack.ts
│   │       ├── PageSubtitle.tsx
│   │       ├── PageTitle.tsx
│   │       ├── PostHogPageView.tsx
│   │       ├── ResizableColumns/
│   │       │   ├── index.ts
│   │       │   └── ui/
│   │       │       └── ResizableColumns.tsx
│   │       ├── Select/
│   │       │   ├── Select.tsx
│   │       │   └── index.ts
│   │       ├── SeverityBorderIcon/
│   │       │   ├── SeverityBorderIcon.tsx
│   │       │   └── index.ts
│   │       ├── SeverityLabel/
│   │       │   ├── SeverityLabel.tsx
│   │       │   └── index.ts
│   │       ├── TabLinkNavigation/
│   │       │   ├── TabLinkNavigation.tsx
│   │       │   ├── TabNavigationLink.tsx
│   │       │   └── index.tsx
│   │       ├── TableIndeterminateCheckbox/
│   │       │   ├── TableIndeterminateCheckbox.tsx
│   │       │   └── index.ts
│   │       ├── TablePagination/
│   │       │   ├── TablePagination.tsx
│   │       │   └── index.ts
│   │       ├── TableSeverityCell/
│   │       │   ├── TableSeverityCell.tsx
│   │       │   └── index.ts
│   │       ├── Tooltip/
│   │       │   ├── Tooltip.tsx
│   │       │   └── index.ts
│   │       ├── TraceViewer/
│   │       │   ├── Trace.ts
│   │       │   ├── TraceViewer.tsx
│   │       │   └── index.ts
│   │       ├── VerticalRoundedList/
│   │       │   ├── VerticalRoundedList.tsx
│   │       │   ├── index.ts
│   │       │   └── vertical-rounded-list.css
│   │       ├── WorkflowYAMLEditor/
│   │       │   ├── index.ts
│   │       │   ├── lib/
│   │       │   │   ├── useYamlValidation.ts
│   │       │   │   └── utils.ts
│   │       │   ├── model/
│   │       │   │   └── types.ts
│   │       │   └── ui/
│   │       │       ├── WorkflowYAMLEditor.tsx
│   │       │       ├── WorkflowYAMLEditorStandalone.tsx
│   │       │       ├── WorkflowYAMLEditorToolbar.tsx
│   │       │       ├── WorkflowYAMLValidationErrors.tsx
│   │       │       └── WorkflowYamlEditorHeader.tsx
│   │       ├── WorkflowYAMLEditorWithLogs/
│   │       │   ├── WorkflowYAMLEditorWithLogs.css
│   │       │   ├── WorkflowYAMLEditorWithLogs.tsx
│   │       │   └── index.tsx
│   │       ├── index.ts
│   │       ├── theme/
│   │       │   ├── ThemeControl.tsx
│   │       │   ├── ThemeScript.tsx
│   │       │   ├── WatchUpdateTheme.ts
│   │       │   └── index.ts
│   │       └── utils/
│   │           ├── favicon.ts
│   │           ├── getIconForStatusString.tsx
│   │           ├── severity-utils.ts
│   │           ├── showErrorToast.tsx
│   │           ├── showSuccessToast.tsx
│   │           └── table-utils.ts
│   ├── styles/
│   │   └── linear.scss
│   ├── tailwind.config.js
│   ├── tsconfig.json
│   ├── tsconfig.scripts.json
│   ├── types/
│   │   ├── auth.d.ts
│   │   ├── internal-config.ts
│   │   └── react-table.d.ts
│   ├── utils/
│   │   ├── apiUrl.ts
│   │   ├── authenticationType.ts
│   │   ├── cel-ast.ts
│   │   ├── fatigue.ts
│   │   ├── helpers.ts
│   │   ├── hooks/
│   │   │   ├── useAI.ts
│   │   │   ├── useAlertPolling.ts
│   │   │   ├── useAlertQuality.ts
│   │   │   ├── useConfig.ts
│   │   │   ├── useDashboardMetricWidgets.ts
│   │   │   ├── useDashboardPresets.ts
│   │   │   ├── useDashboards.ts
│   │   │   ├── useDebouncedValue.ts
│   │   │   ├── useDeduplicationRules.ts
│   │   │   ├── useEnrichmentEvents.ts
│   │   │   ├── useExpandedRows.ts
│   │   │   ├── useExtractionRules.ts
│   │   │   ├── useGroupExpansion.ts
│   │   │   ├── useGroups.ts
│   │   │   ├── useIncidents.ts
│   │   │   ├── useLocalStorage.ts
│   │   │   ├── useMaintenanceRules.ts
│   │   │   ├── useMappingRules.ts
│   │   │   ├── usePermissions.ts
│   │   │   ├── useProviderLogs.ts
│   │   │   ├── useProviders.ts
│   │   │   ├── usePusher.ts
│   │   │   ├── useRoles.ts
│   │   │   ├── useRules.ts
│   │   │   ├── useScopes.ts
│   │   │   ├── useSearchAlerts.ts
│   │   │   ├── useTags.ts
│   │   │   ├── useTenantConfiguration.ts
│   │   │   └── useWorkflowSecrets.ts
│   │   ├── reactFlow.ts
│   │   └── type-utils.ts
│   └── widgets/
│       ├── alerts-table/
│       │   ├── lib/
│       │   │   ├── alert-table-list-format.tsx
│       │   │   ├── alert-table-time-format.tsx
│       │   │   └── alert-table-utils.tsx
│       │   └── ui/
│       │       ├── ActionTraySelection.tsx
│       │       ├── ColumnSelection.tsx
│       │       ├── RowStyleSelection.tsx
│       │       ├── SettingsSelection.tsx
│       │       ├── TitleAndFilters.tsx
│       │       ├── __tests__/
│       │       │   ├── alert-assignee.test.tsx
│       │       │   ├── alert-grouped-row.test.tsx
│       │       │   └── useAlertsTableData.test.ts
│       │       ├── alert-actions.tsx
│       │       ├── alert-assignee.tsx
│       │       ├── alert-extra-payload.tsx
│       │       ├── alert-grouped-row.tsx
│       │       ├── alert-pagination.tsx
│       │       ├── alert-table-column-rename.tsx
│       │       ├── alert-table-headers.tsx
│       │       ├── alert-table-server-side.tsx
│       │       ├── alert-table.tsx
│       │       ├── alerts-table-body.tsx
│       │       └── useAlertsTableData.ts
│       └── workflow-builder/
│           ├── __tests__/
│           │   ├── workflow-builder-widget.test.tsx
│           │   └── workflow-builder.test.tsx
│           ├── empty-builder-state.tsx
│           ├── index.ts
│           ├── workflow-builder-card.tsx
│           ├── workflow-builder-widget-safe.tsx
│           ├── workflow-builder-widget.tsx
│           └── workflow-builder.tsx
├── keycloak/
│   ├── Dockerfile.keycloak
│   ├── KEYCLOAK_LDAP.md
│   ├── docker-compose.yaml
│   ├── event_listeners/
│   │   └── last-login-event-listener-0.0.1-SNAPSHOT.jar
│   ├── generate_ldap.py
│   ├── javascript_providers/
│   │   ├── keep-abac-policy/
│   │   │   ├── META-INF/
│   │   │   │   └── keycloak-scripts.json
│   │   │   └── keep-abac-policy.js
│   │   └── keep-abac-policy.jar
│   ├── jsons/
│   │   ├── group-claim.json
│   │   ├── group-mapper.json
│   │   └── tenant-ids-js-mapper.json
│   ├── keep-realm.json
│   ├── keycloak_entrypoint.sh
│   ├── ldap.ldif
│   ├── ldap_generated.ldif
│   ├── ldif/
│   │   ├── ldap_orgs.ldif
│   │   └── ldap_orgs_new.ldif
│   ├── readme.md
│   └── themes/
│       └── keep.jar
├── oauth2proxy/
│   ├── docker-compose-oauth2proxy.yml
│   └── nginx.conf
├── otel-shared/
│   ├── alertmanager.yml
│   ├── grafana-datasources.yaml
│   ├── otel-collector-config.yaml
│   ├── prometheus.yaml
│   ├── tempo.yaml
│   └── vector.toml
├── prometheus/
│   └── prometheus.yml
├── proxy/
│   ├── README.md
│   ├── docker-compose-proxy.yml
│   ├── nginx.conf
│   └── squid.conf
├── pyproject.toml
├── render.yaml
├── scripts/
│   ├── docs_generate_api_docs_from_openapi.sh
│   ├── docs_get_providers_list.py
│   ├── docs_openapi_converter.py
│   ├── docs_render_provider_snippets.py
│   ├── docs_validate_navigation.sh
│   ├── docs_validate_openapi_is_actual.sh
│   ├── migrate_to_elastic.py
│   ├── save_providers_list.py
│   ├── shoot_alerts_from_dump.py
│   ├── simulate_alerts.py
│   ├── simulate_alerts.sh
│   ├── simulate_rules.py
│   └── workflow_yaml_generate_json_schema.sh
├── start.sh
├── templates/
│   └── CHANGELOG.md
└── tests/
    ├── Dockerfile.keycloak.test
    ├── __init__.py
    ├── cel_to_sql/
    │   ├── cel-to-sql-test-cases.json
    │   ├── order-by-exp-test-cases.json
    │   ├── test_cel_to_ast.py
    │   ├── test_cel_to_sql.py
    │   └── test_order_by_exp.py
    ├── conftest.py
    ├── deduplication/
    │   ├── test_deduplications.py
    │   └── test_deduplications_provisioning.py
    ├── docker-compose-elastic.yml
    ├── docker-compose-keycloak.yml
    ├── docker-compose-mysql.yml
    ├── e2e_tests/
    │   ├── docker-compose-e2e-mysql.yml
    │   ├── docker-compose-e2e-postgres.yml
    │   ├── docker-compose-e2e-redis-sentinel-noauth.yml
    │   ├── docker-compose-e2e-redis.yml
    │   ├── docker-compose-e2e-sqlite.yml
    │   ├── docker-entrypoint-initdb.d/
    │   │   └── update-postgresql-conf.sh
    │   ├── grafana.ini
    │   ├── incidents_alerts_tests/
    │   │   ├── incidents_alerts_setup.py
    │   │   ├── test_filtering_sort_search_on_alerts.py
    │   │   ├── test_filtering_sort_search_on_incidents.py
    │   │   ├── test_mentions_in_incident_comments.py
    │   │   └── test_xss_protection.py
    │   ├── postgres-custom.conf
    │   ├── test_end_to_end.py
    │   ├── test_end_to_end_db_auth.py
    │   ├── test_end_to_end_theme.py
    │   ├── test_grafana_provider.py
    │   ├── test_pushing_prometheus_alerts.py
    │   ├── test_pushing_prometheus_config.yaml
    │   ├── test_pushing_prometheus_rules.yaml
    │   ├── test_redis_sentinel_e2e_full.py
    │   ├── test_topology.py
    │   ├── utils.py
    │   ├── workflow-alert-log.yaml
    │   ├── workflow-incident-log.yaml
    │   ├── workflow-inputs-alert.yaml
    │   ├── workflow-inputs.yaml
    │   ├── workflow-interval.yaml
    │   ├── workflow-invalid-sample.yaml
    │   ├── workflow-quotes-sample.yaml
    │   ├── workflow-sample-npm.yaml
    │   ├── workflow-sample.yaml
    │   └── workflow-valid-sample.yaml
    ├── fixtures/
    │   ├── __init__.py
    │   ├── client.py
    │   └── workflow_manager.py
    ├── keycloak-test-realm-export.json
    ├── providers/
    │   └── jira_provider/
    │       └── test_jira_priority_fix.py
    ├── provision/
    │   ├── workflows_1/
    │   │   ├── provision_example_1.yml
    │   │   ├── provision_example_2.yml
    │   │   └── provision_example_3.yml
    │   ├── workflows_2/
    │   │   ├── provision_example_1.yml
    │   │   └── provision_example_2.yml
    │   ├── workflows_3/
    │   │   └── workflows_with_no_name.yml
    │   └── workflows_4/
    │       └── console_example.yml
    ├── test.json
    ├── test_actions.py
    ├── test_alert_dto.py
    ├── test_alert_evaluation.py
    ├── test_alert_tenrary.py
    ├── test_alert_utils.py
    ├── test_auth.py
    ├── test_auth_new.py
    ├── test_auto_resolve_workflow.py
    ├── test_batch_enrich_cel.py
    ├── test_conditions.py
    ├── test_contextmanager.py
    ├── test_counting.py
    ├── test_counting_integration.py
    ├── test_cyaml.py
    ├── test_dismissal_expiry_bug.py
    ├── test_enrichments.py
    ├── test_extraction_rules.py
    ├── test_functions.py
    ├── test_incidents.py
    ├── test_iohandler.py
    ├── test_jira_provider.py
    ├── test_keep_provider_time_delta.py
    ├── test_maintenance_windows_bl.py
    ├── test_metrics.py
    ├── test_pagerduty_provider.py
    ├── test_parser.py
    ├── test_provider_factory.py
    ├── test_provider_reprovisioning.py
    ├── test_provider_validation_fields.py
    ├── test_providers_api.py
    ├── test_providers_yaml_provisioning.py
    ├── test_provisioning.py
    ├── test_rules_api.py
    ├── test_rules_engine.py
    ├── test_search_alerts.py
    ├── test_search_alerts_configuration.py
    ├── test_secretmanager.py
    ├── test_servicenow_provider.py
    ├── test_settings_api.py
    ├── test_smtp_provider.py
    ├── test_steps.py
    ├── test_teams_provider.py
    ├── test_topology.py
    ├── test_workflow_api.py
    ├── test_workflow_cel_filter.py
    ├── test_workflow_execution.py
    ├── test_workflow_filters.py
    ├── test_workflow_severity_comparisons.py
    ├── test_workflowmanager.py
    ├── test_workflows.py
    ├── test_workflows_update.py
    ├── test_workflowstore.py
    └── workflows/
        ├── db_disk_space_for_testing.yml
        ├── providers_for_testing.yaml
        ├── reusable_actions_for_testing.yml
        ├── reusable_alert_for_testing.yml
        └── reusable_alert_with_actions_for_testing.yml

================================================
FILE CONTENTS
================================================

================================================
FILE: .cursor/rules/keep-ui-react-typescript.mdc
================================================
---
description: 
globs: 
alwaysApply: true
---
---
description: Rules for writing frontend code at Keep (React + Typescript)
globs: keep-ui/**/*.tsx, keep-ui/**/*.ts
---

You are an expert in TypeScript, React, Next.js, SWR, Tailwind, and UX design.

# Achitecture
Use Feature-Slice Design Convention with modification: instead of `pages` and `app` we use default Next.js route-based folder structure.

Example:
- entities/
  - incidents/
    - api/
    - lib/
    - model/
    - ui/

Top-level folders, called Layers: 
- widgets
- features
- entities
- shared

Each layer has segments, e.g. "entities/users".

Each segment has slices 
- ui — everything related to UI display: UI components, date formatters, styles, etc.
- api — backend interactions: request functions, data types, mappers, etc.
- model — the data model: schemas, interfaces, stores, and business logic.
- lib — library code that other modules on this slice need.
- config — configuration files and feature flags.

# Code Style and Structure
- Write TypeScript with proper typing for all new code
- Use functional programming patterns; avoid classes
- Prefer iteration and modularization over code duplication.
- Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError).
- Don't use `useEffect` where you can use ref function for dom-dependent things (e.g. ref={el => ...})
- Don't use `useState` where you can infer from props
- Use named exports; avoid default exports
- If you need to create new base component, first look at existing ones in `@/shared/ui`

# Naming Conventions
- Always look around the codebase for naming conventions, and follow the best practices of the environment (e.g. use `camelCase` variables in JS).
- Use clear, yet functional names (`searchResults` vs `data`).
- React components are PascalCase (`IncidentList`).
- Props for components and hooks are PascalCase and end with `Props`, e.g. `WorkflowBuilderWidgetProps`, return value for hooks is PascalCase and end with `Value`, e.g. `UseIncidentActionsValue` 
- Name the `.ts` file according to its main export: `IncidentList.ts` or `IncidentList.tsx` or `useIncidents.ts`. Pay attention to the case.
- Avoid `index.ts`, `styles.css`, and other generic names, even if this is the only file in a directory.

# Data Fetching
- Use useSWR for fetching data, create or extend hooks in @/entities/<entity>/model/use<Entity>.ts which encapsulates fetching logic
- Create a dedicated keys file @/entities/<entity>/lib/<entity>Keys.ts to manage SWR cache keys. Structure it as an object with methods for different operations:
```export const entityKeys = {
  all: "entityName",
  list: (query: QueryParams) => [...],
  detail: (id: string) => [...],
  getListMatcher: () => (key: any) => boolean
}```
- For query-based endpoints, construct cache keys by joining parameters with "::", filtering out falsy values:
```list: (query: QueryParams) => [
  entityKeys.all,
  "list",
  query.param1,
  query.param2
].filter(Boolean).join("::")```
- For create, update, delete actions:
  - Create or extend hook in @/entities/<entity>/model/use<Entity>Actions.ts
  - Create a dedicated revalidation hook (e.g., use<Entity>Revalidation.ts) to handle cache invalidation
  - Revalidate both specific items and list queries after mutations
  - Include success/error toast notifications for user feedback
  - Handle file uploads and other complex operations within the actions hook

# UI and Styling
- Use Tailwind CSS as primary styling solution
- For non-Tailwind cases:
  - Use CSS with component-specific files
  - Namespace under component class (.DropdownMenu)
  - Follow BEM for modals (.DropdownMenu__modal)
  - Import styles directly (import './DropdownMenu.css')
- Replace custom CSS with Tailwind when possible



================================================
FILE: .cursor/rules/keep-ui-tests.mdc
================================================
---
description: 
globs: 
alwaysApply: true
---
---
description: Rules and guidelines for writing and running React tests
globs: *.spec.tsx, *.test.tsx, *.test.ts, *.spec.ts
---

# Writing frontend tests

Place tests in __tests__ folder in the module, e.g. tests for file `/features/workflows/model/useWorkflows.tsx` should be `/features/workflows/models/__tests__/useWorkflows.test.tsx`

# Running frontend tests

Please run tests with command: npm run test in keep-ui folder
For example: cd keep-ui && npm run test

================================================
FILE: .dockerignore
================================================
docs/*
keep-ui/node_modules
keep-ui/.next/*
keep-ui/.env.local
.venv/
.vercel/
.vscode/
.github/


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: "[🐛 Bug]: "
labels: ""
assignees: ""
---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:

1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Additional context**
Add any other context about the problem here.


================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: true

contact_links:
  - name: Support
    url: https://github.com/keephq/keep/discussions
    about: Get help! Ask questions, get support, and share ideas.

  - name: Chat
    url: https://slack.keephq.dev
    about: Engage with the Keep team and other community members over Slack.

  - name: Twitter
    url: https://twitter.com/keepalerting
    about: Follow us and stay up to date with Keep.


================================================
FILE: .github/ISSUE_TEMPLATE/documentation.md
================================================
---
name: Documentation issue
about: Any issue related with Keep's documentation
title: "[📃 Docs]: "
labels: "Documentation"
assignees: ""
---

**Describe the documentation change**
Add any context about the documentation change you aim to do.


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: "[➕ Feature]: "
labels: ""
assignees: ""
---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.


================================================
FILE: .github/ISSUE_TEMPLATE/new_provider_request.md
================================================
---
name: New provider request
about: Suggest a new provider for keep
title: "[🔌 Provider]: "
labels: "Provider"
assignees: ""
---

**Describe the provider you want to add**
Add any context about the tool and the kind of data you would want to pull/push from the provider.

**Describe your use case**
Does this integration will help you to use Keep?

**Are you already using Keep?**
Yes/No

**Additional context**
Add any other context or screenshots about the provider request here.


================================================
FILE: .github/ISSUE_TEMPLATE/use_case.md
================================================
---
name: Use case
about: Tell us how you use Keep and we will add it to the docs.
title: ''
labels: ''
assignees: ''

---

**What do you use Keep for?**
A clear and concise description of what you do with Keep.


================================================
FILE: .github/workflows/auto-release.yml
================================================
name: Auto Release on Version Change

on:
  push:
    branches:
      - main
    paths:
      - "pyproject.toml"

jobs:
  check-and-release:
    runs-on: ubuntu-latest
    permissions:
      contents: write

    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: "3.11"

      - name: Extract version from pyproject.toml
        id: get_version
        run: |
          VERSION=$(grep '^version = ' pyproject.toml | sed 's/version = "\(.*\)"/\1/')
          echo "version=$VERSION" >> $GITHUB_OUTPUT

      - name: Check if release exists
        id: check_release
        run: |
          TAG_EXISTS=$(git tag -l "v${{ steps.get_version.outputs.version }}")
          if [ -z "$TAG_EXISTS" ]; then
            echo "exists=false" >> $GITHUB_OUTPUT
          else
            echo "exists=true" >> $GITHUB_OUTPUT
          fi

      - name: Create Release
        if: steps.check_release.outputs.exists == 'false'
        uses: softprops/action-gh-release@v1
        with:
          tag_name: v${{ steps.get_version.outputs.version }}
          name: Release v${{ steps.get_version.outputs.version }}
          generate_release_notes: true
          draft: false
          prerelease: false
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


================================================
FILE: .github/workflows/auto-resolve-keep.yml
================================================
name: Auto resolve Keep incident/alert

on:
  workflow_dispatch:
    inputs:
      incident_id:
        description: "Keep incident ID to resolve"
        required: false
        type: string
      alert_fingerprint:
        description: "Keep alert fingerprint to resolve"
        required: false
        type: string
      status:
        description: "Status to set"
        required: false
        type: string
        default: "resolved"
  pull_request:
    types: [closed]
    branches:
      - main

jobs:
  auto-resolve-keep:
    runs-on: ubuntu-latest
    steps:
      - name: Extract Keep ID from PR description
        if: github.event_name == 'pull_request'
        id: extract_id
        run: |
          PR_DESC="${{ github.event.pull_request.body }}"
          INCIDENT_ID=$(echo "$PR_DESC" | grep -ioP 'close keep incident:\s*\K[a-f0-9-]+' || true)
          ALERT_FINGERPRINT=$(echo "$PR_DESC" | grep -ioP 'close keep alert:\s*\K[a-f0-9-]+' || true)
          echo "incident_id=$INCIDENT_ID" >> $GITHUB_OUTPUT
          echo "alert_fingerprint=$ALERT_FINGERPRINT" >> $GITHUB_OUTPUT

      - name: Set final IDs
        id: set_ids
        run: |
          FINAL_INCIDENT_ID="${{ inputs.incident_id || steps.extract_id.outputs.incident_id }}"
          FINAL_ALERT_FINGERPRINT="${{ inputs.alert_fingerprint || steps.extract_id.outputs.alert_fingerprint }}"
          echo "final_incident_id=$FINAL_INCIDENT_ID" >> $GITHUB_OUTPUT
          echo "final_alert_fingerprint=$FINAL_ALERT_FINGERPRINT" >> $GITHUB_OUTPUT

      - name: Auto resolve Keep incident
        if: |
          (github.event_name == 'pull_request' && github.event.pull_request.merged == true && steps.set_ids.outputs.final_incident_id != '') ||
          (github.event_name == 'workflow_dispatch' && inputs.incident_id != '')
        uses: fjogeleit/http-request-action@v1
        with:
          url: "https://api.keephq.dev/incidents/${{ steps.set_ids.outputs.final_incident_id }}/status"
          method: "POST"
          customHeaders: '{"X-API-KEY": "${{ secrets.KEEP_API_KEY }}", "Content-Type": "application/json"}'
          data: '{"status": "${{ inputs.status || ''resolved'' }}"}'

      - name: Auto enrich Keep incident
        if: |
          (github.event_name == 'pull_request' && github.event.pull_request.merged == true && steps.set_ids.outputs.final_incident_id != '') ||
          (github.event_name == 'workflow_dispatch' && inputs.incident_id != '')
        uses: fjogeleit/http-request-action@v1
        with:
          url: "https://api.keephq.dev/incidents/${{ steps.set_ids.outputs.final_incident_id }}/enrich"
          method: "POST"
          customHeaders: '{"X-API-KEY": "${{ secrets.KEEP_API_KEY }}", "Content-Type": "application/json"}'
          data: '{"enrichments":{"incident_title":"${{ github.event.pull_request.title || ''Manual resolution'' }}","incident_url":"${{ github.event.pull_request.html_url || github.server_url }}//${{ github.repository }}/actions/runs/${{ github.run_id }}", "incident_id": "${{ github.run_id }}", "incident_provider": "github"}}'

      - name: Auto resolve Keep alert
        if: |
          (github.event_name == 'pull_request' && github.event.pull_request.merged == true && steps.set_ids.outputs.final_alert_fingerprint != '') ||
          (github.event_name == 'workflow_dispatch' && inputs.alert_fingerprint != '')
        uses: fjogeleit/http-request-action@v1
        with:
          url: "https://api.keephq.dev/alerts/enrich?dispose_on_new_alert=true"
          method: "POST"
          customHeaders: '{"Content-Type": "application/json", "X-API-KEY": "${{ secrets.KEEP_API_KEY }}"}'
          data: '{"enrichments":{"status":"${{ inputs.status || ''resolved'' }}","dismissed":false,"dismissUntil":"","note":"${{ github.event.pull_request.title || ''Manual resolution'' }}","ticket_url":"${{ github.event.pull_request.html_url || github.server_url }}//${{ github.repository }}/actions/runs/${{ github.run_id }}"},"fingerprint":"${{ steps.set_ids.outputs.final_alert_fingerprint }}"}'


================================================
FILE: .github/workflows/but-to-project.yml
================================================
name: Add bugs to project board

on:
  issues:
    types:
      - labeled

jobs:
  add-to-project:
    name: Add bug to project board
    runs-on: ubuntu-latest
    if: github.event.label.name == 'Bug'
    steps:
      - uses: actions/add-to-project@v0.5.0
        with:
          project-url: https://github.com/orgs/keephq/projects/11
          github-token: ${{ secrets.ADD_TO_PROJECT_PAT }}


================================================
FILE: .github/workflows/developer-onboarding-notification.yml
================================================
name: Celebrating Contributions

on:
  pull_request_target:
    types: [closed]

permissions:
  pull-requests: write

jobs:
  comment_on_merged_pull_request:
    if: github.event.pull_request.merged == true
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repository
        uses: actions/checkout@v4

      - name: Set Environment Variables
        env:
          AUTHOR: ${{ github.event.pull_request.user.login }}
          REPO: ${{ github.event.repository.name }}
          OWNER: ${{ github.event.repository.owner.login }}
        run: |
          echo "AUTHOR=${AUTHOR}" >> $GITHUB_ENV
          echo "REPO=${REPO}" >> $GITHUB_ENV
          echo "OWNER=${OWNER}" >> $GITHUB_ENV

      - name: Count Merged Pull Requests
        id: count_merged_pull_requests
        uses: actions/github-script@v6
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            try {
              const author = process.env.AUTHOR;
              const repo = process.env.REPO;
              const owner = process.env.OWNER;
              const { data } = await github.rest.search.issuesAndPullRequests({
                q: `repo:${owner}/${repo} type:pr state:closed author:${author}`
              });
              const prCount = data.items.filter(pr => pr.pull_request.merged_at).length;
              core.exportVariable('PR_COUNT', prCount);
            } catch (error) {
              core.setFailed(`Error counting merged pull requests: ${error.message}`);
            }

      - name: Comment on the Merged Pull Request
        uses: actions/github-script@v6
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            try {
              const prCount = parseInt(process.env.PR_COUNT);
              const author = process.env.AUTHOR;
              const prNumber = context.payload.pull_request.number;
              const repo = process.env.REPO;

              function getRandomEmoji() {
                const emojis = ['🎉', '🚀', '💪', '🌟', '🏆', '🎊', '🔥', '👏', '🌈', '🚂'];
                return emojis[Math.floor(Math.random() * emojis.length)];
              }

              function getMessage(count) {
                const emoji = getRandomEmoji();
                switch(count) {
                  case 1:
                    return `${emoji} **Fantastic work @${author}!** Your very first PR to ${repo} has been merged! 🎉🥳\n\n` +
                           `You've just taken your first step into open-source, and we couldn't be happier to have you onboard. 🙌\n` +
                           `If you're feeling adventurous, why not dive into another issue and keep contributing? The community would love to see more from you! 🚀\n\n` +
                           `For any support, feel free to reach out on the community: https://slack.keephq.dev. Happy coding! 👩‍💻👨‍💻`;
                  case 2:
                    return `${emoji} **Well done @${author}!** Two PRs merged already! 🎉🥳\n\n` +
                           `With your second PR, you're on a roll, and your contributions are already making a difference. 🌟\n` +
                           `Looking forward to seeing even more contributions from you. See you in Slack https://slack.keephq.dev 🚀`;
                  case 3:
                    return `${emoji} **You're on fire, @${author}!** Three PRs merged and counting! 🔥🎉\n\n` +
                           `Your consistent contributions are truly impressive. You're becoming a valued member of our community! 💖\n` +
                           `Have you considered taking on some more challenging issues? We'd love to see what you can do! 💪\n\n` +
                           `Remember, the team is always here to support you. Keep blazing that trail! 🚀`;
                  case 5:
                    return `${emoji} **High five, @${author}!** You've hit the incredible milestone of 5 merged PRs! 🖐️✨\n\n` +
                           `Your dedication to ${repo} is outstanding. You're not just contributing code; you're shaping the future of this project! 🌠\n` +
                           `We'd love to hear your thoughts on the project. Any ideas for new features or improvements? 🤔\n\n` +
                           `The whole team applaud your efforts. You're a superstar! 🌟`;
                  case 10:
                    return `${emoji} **Double digits, @${author}!** 10 merged PRs is a massive achievement! 🏆🎊\n\n` +
                           `Your impact on ${repo} is undeniable. You've become a pillar of our community! 🏛️\n` +
                           `We'd be thrilled to have you take on a mentorship role for newer contributors. Interested? 🧑‍🏫\n\n` +
                           `Everyone here are in awe of your contributions. You're an open source hero! 🦸‍♀️🦸‍♂️`;
                  default:
                    return "";
                }
              }

              const message = getMessage(prCount);

              if (message) {
                await github.rest.issues.createComment({
                  owner: process.env.OWNER,
                  repo: process.env.REPO,
                  issue_number: prNumber,
                  body: message
                });
            }
            } catch (error) {
              core.setFailed(`Error creating comment: ${error.message}`);
            }


================================================
FILE: .github/workflows/lint-pr.yml
================================================
name: "Lint PR"

on:
  pull_request_target:
    types:
      - opened
      - edited
      - synchronize
      - reopened

permissions:
  pull-requests: write # Add explicit permissions for PR comments

jobs:
  main:
    name: Validate PR title
    runs-on: ubuntu-latest
    steps:
      - name: lint_pr_title
        id: lint_pr_title
        uses: amannn/action-semantic-pull-request@v5.1.0
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - uses: marocchino/sticky-pull-request-comment@v2
        # When the previous steps fails, the workflow would stop. By adding this
        # condition you can continue the execution with the populated error message.
        if: always() && (steps.lint_pr_title.outputs.error_message != null)
        with:
          header: pr-title-lint-error
          message: |
            Hey there and thank you for opening this pull request! 👋🏼

            We require pull request titles to follow the [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/) and it looks like your proposed title needs to be adjusted.

            Details:

            ```
            ${{ steps.lint_pr_title.outputs.error_message }}
            ```
      # Delete a previous comment when the issue has been resolved
      - if: ${{ steps.lint_pr_title.outputs.error_message == null }}
        uses: marocchino/sticky-pull-request-comment@v2
        with:
          header: pr-title-lint-error
          delete: true
  links:
    runs-on: ubuntu-latest
    name: Validate PR to Issue link
    permissions:
      issues: read
      pull-requests: write
    steps:
      - uses: nearform-actions/github-action-check-linked-issues@v1
        id: check-linked-issues
        with:
          exclude-branches: "release/**, dependabot/**"
      # OPTIONAL: Use the output from the `check-linked-issues` step
      - name: Get the output
        run: echo "How many linked issues? ${{ steps.check-linked-issues.outputs.linked_issues_count }}"


================================================
FILE: .github/workflows/release-workflow-schema.yml
================================================
name: Release JSON Schema

on:
  push:
    branches:
      - main
    paths:
      - ".github/workflows/release-workflow-schema.yml"
      - "pyproject.toml"
      - "keep/providers/**"
      - "keep-ui/entities/workflows/model/yaml.schema.ts"
  pull_request:
    paths:
      - ".github/workflows/release-workflow-schema.yml"
      - "pyproject.toml"
      - "keep/providers/**"
      - "keep-ui/entities/workflows/model/yaml.schema.ts"
  workflow_dispatch:

env:
  PYTHON_VERSION: 3.11
  STORAGE_MANAGER_DIRECTORY: /tmp/storage-manager
  SCHEMA_REPO_NAME: keephq/keep-workflow-schema
jobs:
  generate-schema:
    runs-on: ubuntu-latest
    permissions:
      contents: read

    outputs:
      version: ${{ steps.get_version.outputs.version }}

    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Extract version from pyproject.toml
        id: get_version
        run: |
          VERSION=$(grep '^version = ' pyproject.toml | sed 's/version = "\(.*\)"/\1/')
          echo "version=$VERSION" >> $GITHUB_OUTPUT

      - name: Set up Python ${{ env.PYTHON_VERSION }}
        uses: actions/setup-python@v4
        with:
          python-version: "3.11"

      - name: Install Poetry
        uses: snok/install-poetry@v1
        with:
          virtualenvs-create: true
          virtualenvs-in-project: true

      - name: Cache dependencies
        id: cache-deps
        uses: actions/cache@v4.2.0
        with:
          path: .venv
          key: pydeps-${{ hashFiles('**/poetry.lock') }}

      - name: Install dependencies using poetry
        run: poetry install --no-interaction --no-root --with dev

      - name: Save providers list
        run: |
          PYTHONPATH="${{ github.workspace }}" poetry run python ./scripts/save_providers_list.py

      - name: Set up Node.js 20
        uses: actions/setup-node@v3
        with:
          node-version: 20
          cache: "npm"
          cache-dependency-path: keep-ui/package-lock.json

      - name: Install Node dependencies
        working-directory: keep-ui
        run: npm ci

      - name: Generate JSON Schema
        working-directory: keep-ui
        run: npm run build:workflow-yaml-json-schema

      - name: Upload schema artifact
        uses: actions/upload-artifact@v4
        with:
          name: workflow-schema
          path: workflow-yaml-json-schema.json

  release-schema:
    runs-on: ubuntu-latest
    needs: generate-schema
    if: ${{ github.event_name != 'pull_request' || !github.event.pull_request.head.repo.fork }}

    steps:
      - name: Download schema artifact
        uses: actions/download-artifact@v4
        with:
          name: workflow-schema
          path: .
      - name: Checkout schema repository
        uses: actions/checkout@v4
        with:
          repository: ${{ env.SCHEMA_REPO_NAME }}
          token: ${{ secrets.SCHEMA_REPO_PAT }}
          path: schema-repo

      - name: Set target branch variable
        id: set_branch
        run: |
          if [ "${{ github.event_name }}" = "pull_request" ]; then
            echo "branch=${{ github.head_ref }}" >> $GITHUB_OUTPUT
          else
            echo "branch=${{ github.ref_name }}" >> $GITHUB_OUTPUT
          fi

      - name: Create or switch to target branch in schema repo
        working-directory: schema-repo
        run: |
          git fetch origin
          if git show-ref --verify --quiet refs/heads/${{ steps.set_branch.outputs.branch }}; then
            git checkout ${{ steps.set_branch.outputs.branch }}
          else
            git checkout -b ${{ steps.set_branch.outputs.branch }}
          fi

      - name: Copy schema to target repository
        run: |
          cp workflow-yaml-json-schema.json schema-repo/schema.json

          # Update schema with version info
          jq --arg version "${{ needs.generate-schema.outputs.version }}" \
             --arg id "https://raw.githubusercontent.com/${{ env.SCHEMA_REPO_NAME }}/v${{ needs.generate-schema.outputs.version }}/schema.json" \
             '. + {version: $version, "$id": $id}' \
             schema-repo/schema.json > schema-repo/schema.tmp.json

          mv schema-repo/schema.tmp.json schema-repo/schema.json

      - name: Check if schema changed
        id: check_changes
        working-directory: schema-repo
        run: |
          git add schema.json
          if git diff --cached --quiet schema.json; then
            echo "changed=false" >> $GITHUB_OUTPUT
          else
            echo "changed=true" >> $GITHUB_OUTPUT
          fi

      - name: Commit and push schema
        if: steps.check_changes.outputs.changed == 'true'
        working-directory: schema-repo
        run: |
          git config user.name "Keep Schema Bot"
          git config user.email "no-reply@keephq.dev"
          git commit -m "Release schema v${{ needs.generate-schema.outputs.version }}"
          git push origin ${{ steps.set_branch.outputs.branch }}
          if [ "${{ steps.set_branch.outputs.branch }}" = "main" ]; then
            git tag "v${{ needs.generate-schema.outputs.version }}"
            git push origin "v${{ needs.generate-schema.outputs.version }}"
          fi

      - name: Create GitHub Release
        if: steps.check_changes.outputs.changed == 'true' && steps.set_branch.outputs.branch == 'main'
        uses: softprops/action-gh-release@v1
        with:
          repository: ${{ env.SCHEMA_REPO_NAME }}
          tag_name: v${{ needs.generate-schema.outputs.version }}
          name: Release v${{ needs.generate-schema.outputs.version }}
          body: |
            Automated release of schema version v${{ needs.generate-schema.outputs.version }}.
        env:
          GITHUB_TOKEN: ${{ secrets.SCHEMA_REPO_PAT }}


================================================
FILE: .github/workflows/release.yml
================================================
name: Keep Release

on:
  workflow_dispatch:

jobs:
  release:
    runs-on: ubuntu-latest
    concurrency: release
    permissions:
      id-token: write
      contents: write
      pull-requests: write

    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
          persist-credentials: false
          ref: main

      - name: Release Keep
        id: release-step
        uses: python-semantic-release/python-semantic-release@v9.8.7
        with:
          git_committer_name: Keep Release Bot
          git_committer_email: no-reply@keephq.dev
          github_token: ${{ secrets.GITHUB_TOKEN }}
          push: false
          tag: true
          commit: true

      - name: Open PR for release branch
        id: pr-step
        uses: peter-evans/create-pull-request@v6.1.0
        with:
          committer: Keep Release Bot <no-reply@keephq.dev>
          title: "Release - ${{ steps.release-step.outputs.version }}"
          branch: release/${{ steps.release-step.outputs.version }}
          body: "This PR contains the latest release changes."
          draft: false
          base: main

      - uses: peter-evans/enable-pull-request-automerge@v3
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          pull-request-number: ${{ steps.pr-step.outputs.pull-request-number }}

      - name: Create release
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          tag: "v${{ steps.release-step.outputs.version }}"
        run: |
          gh release create "$tag" \
              --repo="$GITHUB_REPOSITORY" \
              --title="v${{ steps.release-step.outputs.version }}" \
              --target="release/${{ steps.release-step.outputs.version }}" \
              --generate-notes


================================================
FILE: .github/workflows/run-e2e-tests.yml
================================================
on:
  workflow_call:
    inputs:
      db-type:
        required: true
        type: string
      redis_enabled:
        required: true
        type: boolean
      python-version:
        required: true
        type: string
      is-fork:
        required: true
        type: boolean
      backend-image-name:
        required: true
        type: string
      frontend-image-name:
        required: true
        type: string

jobs:
  # Run tests with all services in one job
  run-tests:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    env:
      REDIS: ${{ inputs.redis_enabled }}
      REDIS_HOST: keep-redis
      REDIS_PORT: 6379
      BACKEND_IMAGE: ${{ inputs.backend-image-name }}
      FRONTEND_IMAGE: ${{ inputs.frontend-image-name }}
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Login to GitHub Container Registry
        if: ${{ inputs.is-fork != true }}
        uses: docker/login-action@v2
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Set up Python ${{ inputs.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ inputs.python-version }}

      - name: Install Poetry
        uses: snok/install-poetry@v1
        with:
          virtualenvs-create: true
          virtualenvs-in-project: true

      - name: Restore dependencies cache
        id: cache-deps
        uses: actions/cache@v4.2.0
        with:
          path: .venv
          key: pydeps-${{ hashFiles('**/poetry.lock') }}

      # Always install dependencies to ensure venv is valid
      # When cached, this completes quickly; when broken, this fixes it
      - name: Install dependencies using poetry
        run: poetry install --no-interaction --no-root --with dev

      - name: Get Playwright version from poetry.lock
        id: playwright-version
        run: |
          PLAYWRIGHT_VERSION=$(grep "playwright" poetry.lock -A 5 | grep "version" | head -n 1 | cut -d'"' -f2)
          echo "version=$PLAYWRIGHT_VERSION" >> $GITHUB_OUTPUT

      - name: Cache Playwright browsers
        id: playwright-cache
        uses: actions/cache@v4.2.0
        with:
          path: ~/.cache/ms-playwright
          key: playwright-${{ steps.playwright-version.outputs.version }}

      - name: Install Playwright and dependencies
        if: steps.playwright-cache.outputs.cache-hit != 'true'
        run: |
          poetry run playwright install --with-deps

      # For forks: Build images locally again since they don't persist between jobs
      - name: Set up Docker Buildx
        if: ${{ inputs.is-fork == true }}
        id: buildx
        uses: docker/setup-buildx-action@v2

      - name: Rebuild frontend image locally for fork PRs
        if: ${{ inputs.is-fork == true }}
        uses: docker/build-push-action@v4
        with:
          context: keep-ui
          file: ./docker/Dockerfile.ui
          push: false
          load: true
          tags: |
            keep-frontend:local
          cache-from: type=gha
          cache-to: type=gha,mode=max
          build-args: |
            BUILDKIT_INLINE_CACHE=1

      - name: Rebuild backend image locally for fork PRs
        if: ${{ inputs.is-fork == true }}
        uses: docker/build-push-action@v4
        with:
          context: .
          file: ./docker/Dockerfile.api
          push: false
          load: true
          tags: |
            keep-backend:local
          cache-from: type=gha
          cache-to: type=gha,mode=max
          build-args: |
            BUILDKIT_INLINE_CACHE=1

      # Create a modified compose file with our built images
      - name: Create modified docker-compose file with built images
        run: |
          cp tests/e2e_tests/docker-compose-e2e-${{ inputs.db-type }}.yml tests/e2e_tests/docker-compose-modified.yml

          # Replace image placeholders with actual image references
          sed -i "s|%KEEPFRONTEND_IMAGE%|${{ env.FRONTEND_IMAGE }}|g" tests/e2e_tests/docker-compose-modified.yml
          sed -i "s|%KEEPBACKEND_IMAGE%|${{ env.BACKEND_IMAGE }}|g" tests/e2e_tests/docker-compose-modified.yml

          # cat the modified file for debugging
          cat tests/e2e_tests/docker-compose-modified.yml

      # Start ALL services in one go
      - name: Start ALL services
        run: |
          echo "Starting ALL services for ${{ inputs.db-type }}..."

          # Pull the required images first (only needed for non-fork builds)
          if [[ "${{ inputs.is-fork }}" != "true" ]]; then
            docker compose -p keep --project-directory . -f tests/e2e_tests/docker-compose-modified.yml pull
          fi

          # Start all services together
          docker compose -p keep --project-directory . -f tests/e2e_tests/docker-compose-modified.yml up -d

          # Show running containers
          docker ps

          # Show the images sha of the running containers
          docker images

      # Wait for all services to be ready
      - name: Wait for services to be ready
        run: |
          # Function for exponential backoff
          function wait_for_service() {
            local service_name=$1
            local check_command=$2
            local max_attempts=$3
            local compose_service=$4  # Docker Compose service name
            local attempt=0
            local wait_time=1

            echo "Waiting for $service_name to be ready..."
            until eval "$check_command"; do
              if [ "$attempt" -ge "$max_attempts" ]; then
                echo "Max attempts reached, exiting..."
                # Show final logs before exiting
                if [ ! -z "$compose_service" ]; then
                  echo "===== FINAL LOGS FOR ON ERROR EXIT $compose_service ====="
                  docker compose -p keep --project-directory . -f tests/e2e_tests/docker-compose-modified.yml logs $compose_service
                  echo "=========================================="
                fi
                exit 1
              fi

              echo "Waiting for $service_name... (Attempt: $((attempt+1)), waiting ${wait_time}s)"

              # Print logs using docker compose
              if [ ! -z "$compose_service" ]; then
                echo "===== RECENT LOGS FOR $compose_service ====="
                docker compose -p keep --project-directory . -f tests/e2e_tests/docker-compose-modified.yml logs $compose_service --tail 100
                echo "=========================================="
              fi

              attempt=$((attempt+1))
              sleep $wait_time
              # Exponential backoff with max of 8 seconds
              wait_time=$((wait_time * 2 > 8 ? 8 : wait_time * 2))
            done
            echo "$service_name is ready!"

            # last time, print logs using docker compose
            if [ ! -z "$compose_service" ]; then
              echo "===== FINAL LOGS FOR $compose_service ====="
              docker compose -p keep --project-directory . -f tests/e2e_tests/docker-compose-modified.yml logs $compose_service --tail 100
              echo "=========================================="
            fi
          }

          # Database checks
          if [ "${{ inputs.db-type }}" == "mysql" ]; then
            wait_for_service "MySQL Database" "docker compose -p keep --project-directory . -f tests/e2e_tests/docker-compose-modified.yml exec -T keep-database mysqladmin ping -h \"localhost\" --silent" 10 "keep-database"
            wait_for_service "MySQL Database (DB AUTH)" "docker compose -p keep --project-directory . -f tests/e2e_tests/docker-compose-modified.yml exec -T keep-database-db-auth mysqladmin ping -h \"localhost\" --silent" 10 "keep-database-db-auth"
          elif [ "${{ inputs.db-type }}" == "postgres" ]; then
            wait_for_service "Postgres Database" "docker compose -p keep --project-directory . -f tests/e2e_tests/docker-compose-modified.yml exec -T keep-database pg_isready -h localhost -U keepuser" 10 "keep-database"
            wait_for_service "Postgres Database (DB AUTH)" "docker compose -p keep --project-directory . -f tests/e2e_tests/docker-compose-modified.yml exec -T keep-database-db-auth pg_isready -h localhost -U keepuser" 10 "keep-database-db-auth"
          fi

          # Wait for services with health checks
          wait_for_service "Keep backend" "curl --output /dev/null --silent --fail http://localhost:8080/healthcheck" 15 "keep-backend"
          wait_for_service "Keep backend (DB AUTH)" "curl --output /dev/null --silent --fail http://localhost:8081/healthcheck" 15 "keep-backend-db-auth"
          wait_for_service "Keep frontend" "curl --output /dev/null --silent --fail http://localhost:3000/" 15 "keep-frontend"
          wait_for_service "Keep frontend (DB AUTH)" "curl --output /dev/null --silent --fail http://localhost:3001/" 15 "keep-frontend-db-auth"

          # Give Prometheus and Grafana extra time to initialize
          # (using direct curl commands instead of container exec)
          echo "Waiting for Prometheus to be ready..."
          MAX_ATTEMPTS=15
          for i in $(seq 1 $MAX_ATTEMPTS); do
            if curl --output /dev/null --silent --fail http://localhost:9090/-/healthy; then
              echo "Prometheus is ready!"
              break
            elif [ $i -eq $MAX_ATTEMPTS ]; then
              echo "Prometheus did not become ready in time, but continuing..."
              docker compose -p keep --project-directory . -f tests/e2e_tests/docker-compose-modified.yml logs prometheus-server-for-test-target --tail 50
            else
              echo "Waiting for Prometheus... Attempt $i/$MAX_ATTEMPTS"
              sleep 5
            fi
          done

          echo "Waiting for Grafana to be ready..."
          MAX_ATTEMPTS=15
          for i in $(seq 1 $MAX_ATTEMPTS); do
            if curl --output /dev/null --silent --fail http://localhost:3002/api/health; then
              echo "Grafana is ready!"
              break
            elif [ $i -eq $MAX_ATTEMPTS ]; then
              echo "Grafana did not become ready in time, but continuing..."
              docker compose -p keep --project-directory . -f tests/e2e_tests/docker-compose-modified.yml logs grafana --tail 50
            else
              echo "Waiting for Grafana... Attempt $i/$MAX_ATTEMPTS"
              sleep 5
            fi
          done

          # Give everything a bit more time to stabilize
          echo "Giving services additional time to stabilize..."
          sleep 10

      # Debug the environment before running tests
      - name: Debug environment
        run: |
          echo "Checking all container status..."
          docker compose -p keep --project-directory . -f tests/e2e_tests/docker-compose-modified.yml ps

          echo "Network information:"
          docker network ls
          docker network inspect keep_default || true

          echo "Testing Prometheus API..."
          curl -v http://localhost:9090/api/v1/status/config || echo "Prometheus API not responding, but continuing..."

          echo "Testing Grafana API..."
          curl -v http://localhost:3002/api/health || echo "Grafana API not responding, but continuing..."

          echo "Test Keep Frontend..."
          curl -v http://localhost:3000/ || echo "Keep Frontend not responding, but continuing..."

          echo "Test Keep Frontend with DB Auth..."
          curl -v http://localhost:3001/ || echo "Keep Frontend with DB Auth not responding, but continuing..."

          echo "Listing available ports:"
          netstat -tuln | grep -E '3000|3001|3002|8080|8081|9090'

      # Run e2e tests
      - name: Run e2e tests and report coverage
        run: |
          echo "Running tests..."
          poetry run coverage run --branch -m pytest -v tests/e2e_tests/ -n 4 --dist=loadfile
          echo "Tests completed!"

      - name: Convert coverage results to JSON (for CodeCov support)
        run: poetry run coverage json --omit="keep/providers/*"

      - name: Upload coverage reports to Codecov
        uses: codecov/codecov-action@v3
        with:
          fail_ci_if_error: false
          files: coverage.json
          verbose: true

      # Collect logs
      - name: Dump logs
        if: always()
        run: |
          docker compose -p keep --project-directory . -f tests/e2e_tests/docker-compose-modified.yml logs keep-backend > backend_logs-${{ inputs.db-type }}.txt
          docker compose -p keep --project-directory . -f tests/e2e_tests/docker-compose-modified.yml logs keep-frontend > frontend_logs-${{ inputs.db-type }}.txt
          docker compose -p keep --project-directory . -f tests/e2e_tests/docker-compose-modified.yml logs keep-backend-db-auth > backend_logs-${{ inputs.db-type }}-db-auth.txt
          docker compose -p keep --project-directory . -f tests/e2e_tests/docker-compose-modified.yml logs keep-frontend-db-auth > frontend_logs-${{ inputs.db-type }}-db-auth.txt
          docker compose -p keep --project-directory . -f tests/e2e_tests/docker-compose-modified.yml logs prometheus-server-for-test-target > prometheus_logs-${{ inputs.db-type }}.txt
          docker compose -p keep --project-directory . -f tests/e2e_tests/docker-compose-modified.yml logs grafana > grafana_logs-${{ inputs.db-type }}.txt
        continue-on-error: true

      # Upload artifacts
      - name: Upload test artifacts on failure
        if: always()
        uses: actions/upload-artifact@v4.4.3
        with:
          name: test-artifacts-db-${{ inputs.db-type }}-redis-${{ inputs.redis_enabled }}
          path: |
            playwright_dump_*.html
            playwright_dump_*.png
            playwright_dump_*.txt
            playwright_dump_*.json
            backend_logs-${{ inputs.db-type }}.txt
            frontend_logs-${{ inputs.db-type }}.txt
            backend_logs-${{ inputs.db-type }}-db-auth.txt
            frontend_logs-${{ inputs.db-type }}-db-auth.txt
            prometheus_logs-${{ inputs.db-type }}.txt
            grafana_logs-${{ inputs.db-type }}.txt
        continue-on-error: true

      # Tear down environment
      - name: Tear down environment
        if: always()
        run: |
          docker compose -p keep --project-directory . -f tests/e2e_tests/docker-compose-modified.yml down


================================================
FILE: .github/workflows/sync-keep-workflows.yml
================================================
# A workflow that sync Keep workflows from a directory
name: "Sync Keep Workflows"

on:
    workflow_dispatch:
        inputs:
            keep_api_key:
              description: 'Keep API Key'
              required: false
            keep_api_url:
              description: 'Keep API URL'
              required: false
              default: 'https://api.keephq.dev'
    # push:
    #     paths:
    #       - 'examples/workflows/**'

jobs:
    sync-workflows:
        name: Sync workflows to Keep
        runs-on: ubuntu-latest
        # Use the Keep CLI image
        container:
            image: us-central1-docker.pkg.dev/keephq/keep/keep-cli:latest
        env:
            KEEP_API_KEY: ${{ secrets.KEEP_API_KEY || github.event.inputs.keep_api_key }}
            KEEP_API_URL: ${{ secrets.KEEP_API_URL || github.event.inputs.keep_api_url }}

        steps:
        - name: Check out the repo
          uses: actions/checkout@v2

        - name: Run Keep CLI
          run: |
            keep workflow apply -f examples/workflows


================================================
FILE: .github/workflows/test-docs.yml
================================================
name: Test docs
on:
  push:
    paths:
      - 'keep/providers/**'
      - 'docs/**'
      - 'examples/**'
  pull_request:
    paths:
      - 'keep/providers/**'
      - 'docs/**'
      - 'examples/**'
  workflow_dispatch:
concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref }}-${{ github.job }}
  cancel-in-progress: true
env:
  PYTHON_VERSION: 3.11
  STORAGE_MANAGER_DIRECTORY: /tmp/storage-manager

jobs:
  tests-docs:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - uses: chartboost/ruff-action@v1
        with:
          src: "./keep"
      - name: Set up Python ${{ env.PYTHON_VERSION }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ env.PYTHON_VERSION }}

      - name: Install Poetry
        uses: snok/install-poetry@v1
        with:
          virtualenvs-create: true
          virtualenvs-in-project: true

      - name: cache deps
        id: cache-deps
        uses: actions/cache@v4.2.0
        with:
          path: .venv
          key: pydeps-${{ hashFiles('**/poetry.lock') }}

      - name: Install dependencies using poetry
        run: poetry install --no-interaction --no-root --with dev
  
      - name: Validate docs/providers/overview.mdx
        run: |
          cd scripts;
          poetry run python ./docs_get_providers_list.py --validate    

      - name: Validate snippets for providers
        run: |
          poetry run python ./scripts/docs_render_provider_snippets.py --validate  

      - name: Validate broken links and navigation
        run: |
          npm i -g mintlify;
          
          cd docs && mintlify broken-links;
          cd ../scripts;
          ./docs_validate_navigation.sh;

          # Todo: validate if openapi schema is matching with the code
  

================================================
FILE: .github/workflows/test-pr-e2e.yml
================================================
name: Tests (E2E)

on:
  workflow_dispatch:
  pull_request:
    paths:
      - "keep/**"
      - "keep-ui/**"
      - "tests/**"

# Add permissions for GitHub Container Registry
permissions:
  contents: read
  packages: write

concurrency:
  group: ${{ github.event_name }}-${{ github.workflow }}-${{ github.head_ref }}
  cancel-in-progress: true

env:
  PYTHON_VERSION: 3.11
  STORAGE_MANAGER_DIRECTORY: /tmp/storage-manager
  # MySQL server environment variables
  MYSQL_ROOT_PASSWORD: keep
  MYSQL_DATABASE: keep
  # Postgres environment variables
  POSTGRES_USER: keepuser
  POSTGRES_PASSWORD: keeppassword
  POSTGRES_DB: keepdb
  # To test if imports are working properly
  EE_ENABLED: true
  # Docker Compose project name
  COMPOSE_PROJECT_NAME: keep
  # Check if PR is from fork (external contributor)
  IS_FORK: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork }}

jobs:
  # Prepare test environment in parallel with Docker builds
  prepare-test-environment:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Set up Python ${{ env.PYTHON_VERSION }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ env.PYTHON_VERSION }}

      - name: Install Poetry
        uses: snok/install-poetry@v1
        with:
          virtualenvs-create: true
          virtualenvs-in-project: true

      - name: Cache dependencies
        id: cache-deps
        uses: actions/cache@v4.2.0
        with:
          path: .venv
          key: pydeps-${{ hashFiles('**/poetry.lock') }}

      - name: Install dependencies using poetry
        run: poetry install --no-interaction --no-root --with dev

      - name: Get Playwright version from poetry.lock
        id: playwright-version
        run: |
          PLAYWRIGHT_VERSION=$(grep "playwright" poetry.lock -A 5 | grep "version" | head -n 1 | cut -d'"' -f2)
          echo "version=$PLAYWRIGHT_VERSION" >> $GITHUB_OUTPUT

      - name: Cache Playwright browsers
        id: playwright-cache
        uses: actions/cache@v4.2.0
        with:
          path: ~/.cache/ms-playwright
          key: playwright-${{ steps.playwright-version.outputs.version }}

      - name: Install Playwright and dependencies
        run: |
          if [ "${{ steps.playwright-cache.outputs.cache-hit }}" != "true" ]; then
            poetry run playwright install --with-deps
          else
            poetry run playwright install-deps
          fi

  # Build images in parallel
  build-frontend:
    runs-on: ubuntu-latest
    outputs:
      image_name: ${{ steps.set-image-name.outputs.image_name }}
    permissions:
      contents: read
      packages: write
    steps:
      - name: Set image name
        id: set-image-name
        run: |
          if [[ "${{ env.IS_FORK }}" == "true" ]]; then
            echo "image_name=keep-frontend:local" >> $GITHUB_OUTPUT
          else
            echo "image_name=ghcr.io/${{ github.repository_owner }}/keep-frontend:${{ github.sha }}" >> $GITHUB_OUTPUT
          fi

      - name: Login to GitHub Container Registry
        if: ${{ env.IS_FORK != 'true' }}
        uses: docker/login-action@v2
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Checkout
        uses: actions/checkout@v3

      - name: Set up Docker Buildx
        id: buildx
        uses: docker/setup-buildx-action@v2

      - name: Set cache key variables
        id: cache-keys
        run: |
          # Create a safe branch name for cache key (replace / with - and remove special chars)
          SAFE_BRANCH=$(echo "${{ github.head_ref || github.ref_name }}" | sed 's/\//-/g' | sed 's/[^a-zA-Z0-9._-]//g')
          echo "SAFE_BRANCH_NAME=${SAFE_BRANCH}" >> $GITHUB_OUTPUT

          # Create a hash ONLY of the dependencies section of package.json and package-lock.json
          # This ensures the hash only changes when dependencies change
          DEPS_HASH=$(jq '.dependencies' keep-ui/package.json | sha256sum | cut -d ' ' -f 1)
          echo "DEPS_HASH=${DEPS_HASH:0:8}" >> $GITHUB_OUTPUT

      - name: Debug repository and cache info
        run: |
          echo "Repository: ${{ github.repository }}"
          echo "Repository owner: ${{ github.repository_owner }}"
          echo "Branch: ${{ github.head_ref || github.ref_name }}"
          echo "Safe branch name: ${{ steps.cache-keys.outputs.SAFE_BRANCH_NAME }}"
          echo "Dependencies hash: ${{ steps.cache-keys.outputs.DEPS_HASH }}"
          echo "Is fork: ${{ env.IS_FORK }}"

      # Pre-check if branch cache exists (only for non-forks)
      - name: Check if branch cache exists
        id: branch-cache-exists
        if: ${{ env.IS_FORK != 'true' }}
        continue-on-error: true
        run: |
          BRANCH_CACHE_TAG="ghcr.io/${{ github.repository_owner }}/keep-frontend:cache-${{ steps.cache-keys.outputs.SAFE_BRANCH_NAME }}"
          if docker buildx imagetools inspect "$BRANCH_CACHE_TAG" &>/dev/null; then
            echo "Branch cache exists: $BRANCH_CACHE_TAG"
            echo "cache_exists=true" >> $GITHUB_OUTPUT
          else
            echo "Branch cache does not exist: $BRANCH_CACHE_TAG"
            echo "cache_exists=false" >> $GITHUB_OUTPUT
          fi

      - name: Log frontend cache status
        if: ${{ env.IS_FORK != 'true' }}
        run: |
          if [ "${{ steps.branch-cache-exists.outputs.cache_exists }}" == "true" ]; then
            echo "FRONTEND CACHE HIT ✅"
            echo "Cache tag: ghcr.io/${{ github.repository_owner }}/keep-frontend:cache-${{ steps.cache-keys.outputs.SAFE_BRANCH_NAME }}"
          else
            echo "FRONTEND CACHE MISS ❌"
            echo "Will attempt to use main branch cache and create a new branch cache"
          fi

      # For non-forks: Build and push to registry
      - name: Build and push frontend image with registry cache
        if: ${{ env.IS_FORK != 'true' }}
        uses: docker/build-push-action@v4
        with:
          context: keep-ui
          file: ./docker/Dockerfile.ui
          push: true
          tags: |
            ghcr.io/${{ github.repository_owner }}/keep-frontend:${{ github.sha }}
          # Use registry-based caching with branch-specific tags
          cache-from: |
            type=registry,ref=ghcr.io/${{ github.repository_owner }}/keep-frontend:cache-${{ steps.cache-keys.outputs.SAFE_BRANCH_NAME }}
            type=registry,ref=ghcr.io/${{ github.repository_owner }}/keep-frontend:cache-${{ steps.cache-keys.outputs.DEPS_HASH }}
            type=registry,ref=ghcr.io/${{ github.repository_owner }}/keep-frontend:cache-main
          cache-to: |
            type=registry,ref=ghcr.io/${{ github.repository_owner }}/keep-frontend:cache-${{ steps.cache-keys.outputs.SAFE_BRANCH_NAME }},mode=max
            type=registry,ref=ghcr.io/${{ github.repository_owner }}/keep-frontend:cache-${{ steps.cache-keys.outputs.DEPS_HASH }},mode=max
          # Add build args for better caching
          build-args: |
            BUILDKIT_INLINE_CACHE=1
          # Verbose output
          outputs: type=image,push=true

  build-backend:
    runs-on: ubuntu-latest
    outputs:
      image_name: ${{ steps.set-image-name.outputs.image_name }}
    permissions:
      contents: read
      packages: write
    steps:
      - name: Set image name
        id: set-image-name
        run: |
          if [[ "${{ env.IS_FORK }}" == "true" ]]; then
            echo "image_name=keep-backend:local" >> $GITHUB_OUTPUT
          else
            echo "image_name=ghcr.io/${{ github.repository_owner }}/keep-backend:${{ github.sha }}" >> $GITHUB_OUTPUT
          fi

      - name: Login to GitHub Container Registry
        if: ${{ env.IS_FORK != 'true' }}
        uses: docker/login-action@v2
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Checkout
        uses: actions/checkout@v3

      - name: Set up Docker Buildx
        id: buildx
        uses: docker/setup-buildx-action@v2

      - name: Set cache key variables
        id: cache-keys
        run: |
          # Create a safe branch name for cache key (replace / with - and remove special chars)
          SAFE_BRANCH=$(echo "${{ github.head_ref || github.ref_name }}" | sed 's/\//-/g' | sed 's/[^a-zA-Z0-9._-]//g')
          echo "SAFE_BRANCH_NAME=${SAFE_BRANCH}" >> $GITHUB_OUTPUT

          # Create a hash of poetry files for version-specific caching
          DEPS_HASH=$(cat poetry.lock pyproject.toml | sha256sum | cut -d ' ' -f 1)
          echo "DEPS_HASH=${DEPS_HASH:0:8}" >> $GITHUB_OUTPUT

      - name: Debug repository and cache info
        run: |
          echo "Repository: ${{ github.repository }}"
          echo "Repository owner: ${{ github.repository_owner }}"
          echo "Branch: ${{ github.head_ref || github.ref_name }}"
          echo "Safe branch name: ${{ steps.cache-keys.outputs.SAFE_BRANCH_NAME }}"
          echo "Dependencies hash: ${{ steps.cache-keys.outputs.DEPS_HASH }}"
          echo "Is fork: ${{ env.IS_FORK }}"

      # Pre-check if branch cache exists (only for non-forks)
      - name: Check if branch cache exists
        id: branch-cache-exists
        if: ${{ env.IS_FORK != 'true' }}
        continue-on-error: true
        run: |
          BRANCH_CACHE_TAG="ghcr.io/${{ github.repository_owner }}/keep-backend:cache-${{ steps.cache-keys.outputs.SAFE_BRANCH_NAME }}"
          if docker buildx imagetools inspect "$BRANCH_CACHE_TAG" &>/dev/null; then
            echo "Branch cache exists: $BRANCH_CACHE_TAG"
            echo "cache_exists=true" >> $GITHUB_OUTPUT
          else
            echo "Branch cache does not exist: $BRANCH_CACHE_TAG"
            echo "cache_exists=false" >> $GITHUB_OUTPUT
          fi

      - name: Log backend cache status
        if: ${{ env.IS_FORK != 'true' }}
        run: |
          if [ "${{ steps.branch-cache-exists.outputs.cache_exists }}" == "true" ]; then
            echo "BACKEND CACHE HIT ✅"
            echo "Cache tag: ghcr.io/${{ github.repository_owner }}/keep-backend:cache-${{ steps.cache-keys.outputs.SAFE_BRANCH_NAME }}"
          else
            echo "BACKEND CACHE MISS ❌"
            echo "Will attempt to use main branch cache and create a new branch cache"
          fi

      # For non-forks: Build and push to registry
      - name: Build and push backend image with registry cache
        if: ${{ env.IS_FORK != 'true' }}
        uses: docker/build-push-action@v4
        with:
          context: .
          file: ./docker/Dockerfile.api
          push: true
          tags: |
            ghcr.io/${{ github.repository_owner }}/keep-backend:${{ github.sha }}
          # Use registry-based caching with branch-specific tags
          cache-from: |
            type=registry,ref=ghcr.io/${{ github.repository_owner }}/keep-backend:cache-${{ steps.cache-keys.outputs.DEPS_HASH }}
            type=registry,ref=ghcr.io/${{ github.repository_owner }}/keep-backend:cache-${{ steps.cache-keys.outputs.SAFE_BRANCH_NAME }}
          cache-to: |
            type=registry,ref=ghcr.io/${{ github.repository_owner }}/keep-backend:cache-${{ steps.cache-keys.outputs.DEPS_HASH }},mode=max
            type=registry,ref=ghcr.io/${{ github.repository_owner }}/keep-backend:cache-${{ steps.cache-keys.outputs.SAFE_BRANCH_NAME }},mode=max
          # Add build args for better caching
          build-args: |
            BUILDKIT_INLINE_CACHE=1
          # Verbose output
          outputs: type=image,push=true

  # Run tests with all services in one job
  run-mysql-with-redis:
    needs: [build-frontend, build-backend, prepare-test-environment]
    uses: ./.github/workflows/run-e2e-tests.yml
    with:
      db-type: mysql
      redis_enabled: true
      python-version: 3.11
      is-fork: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork }}
      backend-image-name: ${{ needs.build-backend.outputs.image_name }}
      frontend-image-name: ${{ needs.build-frontend.outputs.image_name }}
  
  run-postgresql-without-redis:
    needs: [build-frontend, build-backend, prepare-test-environment]
    uses: ./.github/workflows/run-e2e-tests.yml
    with:
      db-type: postgres
      redis_enabled: false
      python-version: 3.11
      is-fork: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork }}
      backend-image-name: ${{ needs.build-backend.outputs.image_name }}
      frontend-image-name: ${{ needs.build-frontend.outputs.image_name }}
  
  run-sqlite-without-redis:
    needs: [build-frontend, build-backend, prepare-test-environment]
    uses: ./.github/workflows/run-e2e-tests.yml
    with:
      db-type: sqlite
      redis_enabled: false
      python-version: 3.11
      is-fork: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork }}
      backend-image-name: ${{ needs.build-backend.outputs.image_name }}
      frontend-image-name: ${{ needs.build-frontend.outputs.image_name }}

================================================
FILE: .github/workflows/test-pr-integrations.yml
================================================
name: Integration Tests
on:
  push:
    branches:
      - main
    paths:
      - "keep/**"
      - "tests/**"
  pull_request:
    paths:
      - "keep/**"
      - "tests/**"
  workflow_dispatch:

permissions:
  actions: write

concurrency:
  group: ${{ github.event_name }}-${{ github.workflow }}-${{ github.head_ref }}
  cancel-in-progress: true

env:
  PYTHON_VERSION: 3.11
  STORAGE_MANAGER_DIRECTORY: /tmp/storage-manager
  MYSQL_ROOT_PASSWORD: keep
  MYSQL_DATABASE: keep
  ELASTIC_PASSWORD: keeptests

jobs:
  integration-tests:
    runs-on: ubuntu-latest
    services:
      mysql:
        image: mysql:5.7
        env:
          MYSQL_ROOT_PASSWORD: ${{ env.MYSQL_ROOT_PASSWORD }}
          MYSQL_DATABASE: ${{ env.MYSQL_DATABASE }}
        ports:
          - 3306:3306
        options: >-
          --health-cmd="mysqladmin ping"
          --health-interval=10s
          --health-timeout=5s
          --health-retries=3
      elasticsearch:
        image: docker.elastic.co/elasticsearch/elasticsearch:8.13.4
        ports:
          - 9200:9200
        env:
          ELASTIC_PASSWORD: ${{ env.ELASTIC_PASSWORD }}
          bootstrap.memory_lock: "true"
          discovery.type: "single-node"
          ES_JAVA_OPTS: "-Xms2g -Xmx2g"
          xpack.security.enabled: "true"
      keycloak:
        image: us-central1-docker.pkg.dev/keephq/keep/keep-keycloak-test
        env:
          KC_DB: dev-mem
          KC_HTTP_RELATIVE_PATH: /auth
          KEYCLOAK_ADMIN: keep_kc_admin
          KEYCLOAK_ADMIN_PASSWORD: keep_kc_admin
        ports:
          - 8787:8080
        options: >-
          --health-cmd="/opt/keycloak/bin/kcadm.sh config credentials --server http://localhost:8080/auth --realm master --user keep_kc_admin --password keep_kc_admin || exit 1"
          --health-interval=10s
          --health-timeout=5s
          --health-retries=4

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Set up Python ${{ env.PYTHON_VERSION }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ env.PYTHON_VERSION }}

      - name: Install Poetry
        uses: snok/install-poetry@v1
        with:
          virtualenvs-create: true
          virtualenvs-in-project: true

      - name: cache deps
        id: cache-deps
        uses: actions/cache@v4.2.0
        with:
          path: .venv
          key: pydeps-${{ hashFiles('**/poetry.lock') }}

      - name: Install dependencies using poetry
        run: poetry install --no-interaction --no-root --with dev

      - name: Run integration tests and report coverage
        run: |
          until nc -z 127.0.0.1 3306; do
            echo "waiting for MySQL..."
            sleep 1
          done
          echo "MySQL is up and running!"
          poetry run coverage run --omit="*/test*" --branch -m pytest --integration --ignore=tests/e2e_tests/

      - name: Convert coverage results to JSON
        run: poetry run coverage json --omit="keep/providers/*"

      - name: Upload coverage reports to Codecov
        uses: codecov/codecov-action@v3
        with:
          fail_ci_if_error: false
          files: coverage.json
          verbose: true


================================================
FILE: .github/workflows/test-pr-ut-ui.yml
================================================
name: Frontend Tests
on:
  push:
    branches:
      - main
    paths:
      - "keep-ui/**"
  pull_request:
    paths:
      - "keep-ui/**"
  workflow_dispatch:

permissions:
  actions: write

concurrency:
  group: ${{ github.event_name }}-${{ github.workflow }}-${{ github.head_ref }}
  cancel-in-progress: true

env:
  NODE_VERSION: 20

jobs:
  frontend-tests:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Set up Node.js ${{ env.NODE_VERSION }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'
          cache-dependency-path: keep-ui/package-lock.json

      - name: Install dependencies
        working-directory: keep-ui
        run: npm ci

      - name: Run frontend tests
        working-directory: keep-ui
        run: npm run test

      # Optional: Add coverage reporting if your test setup supports it
      # Uncomment and adjust if you have coverage reporting configured
      # - name: Upload coverage reports to Codecov
      #   uses: codecov/codecov-action@v3
      #   with:
      #     fail_ci_if_error: false
      #     directory: keep-ui/coverage
      #     flags: frontend
      #     verbose: true 

================================================
FILE: .github/workflows/test-pr-ut.yml
================================================
name: Unit Tests
on:
  push:
    branches:
      - main
    paths:
      - "keep/**"
      - "tests/**"
  pull_request:
    paths:
      - "keep/**"
      - "tests/**"
  workflow_dispatch:

permissions:
  actions: write

concurrency:
  group: ${{ github.event_name }}-${{ github.workflow }}-${{ github.head_ref }}
  cancel-in-progress: true

env:
  PYTHON_VERSION: 3.11
  SQLALCHEMY_WARN_20: 1

jobs:
  unit-tests:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - uses: chartboost/ruff-action@v1
        with:
          src: "./keep"

      - name: Set up Python ${{ env.PYTHON_VERSION }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ env.PYTHON_VERSION }}

      - name: Install Poetry
        uses: snok/install-poetry@v1
        with:
          virtualenvs-create: true
          virtualenvs-in-project: true

      - name: cache deps
        id: cache-deps
        uses: actions/cache@v4.2.0
        with:
          path: .venv
          key: pydeps-${{ hashFiles('**/poetry.lock') }}

      - name: Install dependencies using poetry
        run: poetry install --no-interaction --no-root --with dev

      - name: Run unit tests and report coverage
        run: |
          poetry run coverage run --omit="*/test*" --branch -m pytest --timeout 20 -n auto --non-integration --ignore=tests/e2e_tests/

      - name: Convert coverage results to JSON
        run: poetry run coverage json --omit="keep/providers/*"

      - name: Upload coverage reports to Codecov
        uses: codecov/codecov-action@v3
        with:
          fail_ci_if_error: false
          files: coverage.json
          verbose: true


================================================
FILE: .github/workflows/test-workflow-examples.yml
================================================
name: Test workflow examples
on:
  push:
    paths:
      - 'keep/providers/**'
      - 'examples/workflows/**'
      - 'keep-ui/entities/workflows/model/yaml.schema.ts'
      - 'keep-ui/scripts/validate-workflow-examples.ts'
  pull_request:
    paths:
      - 'keep/providers/**'
      - 'examples/workflows/**'
      - 'keep-ui/entities/workflows/model/yaml.schema.ts'
      - 'keep-ui/scripts/validate-workflow-examples.ts'
  workflow_dispatch:
concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref }}-${{ github.job }}
  cancel-in-progress: true
env:
  NODE_VERSION: 20
  PYTHON_VERSION: 3.11
  STORAGE_MANAGER_DIRECTORY: /tmp/storage-manager

jobs:
  test-workflow-examples:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - uses: chartboost/ruff-action@v1
        with:
          src: "./keep"

      - name: Set up Python ${{ env.PYTHON_VERSION }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ env.PYTHON_VERSION }}

      - name: Install Poetry
        uses: snok/install-poetry@v1
        with:
          virtualenvs-create: true
          virtualenvs-in-project: true

      - name: cache deps
        id: cache-deps
        uses: actions/cache@v4.2.0
        with:
          path: .venv
          key: pydeps-${{ hashFiles('**/poetry.lock') }}

      - name: Install dependencies using poetry
        run: poetry install --no-interaction --no-root --with dev

      # Save list of providers to providers_list.json, because we don't have backend endpoint to get it
      - name: Save providers list
        run: |
          PYTHONPATH="${{ github.workspace }}" poetry run python ./scripts/save_providers_list.py

      - name: Set up Node.js ${{ env.NODE_VERSION }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'
          cache-dependency-path: keep-ui/package-lock.json

      - name: Install dependencies
        working-directory: keep-ui
        run: npm ci

      - name: Run workflow examples validation
        working-directory: keep-ui
        run: npm run test:workflow-examples


================================================
FILE: .gitignore
================================================
# .DS_STORE
.DS_Store
**/.DS_Store

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# .csv files
*.csv

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
#  Usually these files are written by a python script from a template
#  before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.lcov
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.pybuilder/
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
#   For a library or package, you might want to ignore these files since the code is
#   intended to run in multiple environments; otherwise, check them in:
# .python-version

# pipenv
#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
#   However, in case of collaboration, if having platform-specific dependencies or dependencies
#   having no cross-platform support, pipenv may install dependencies that don't work, or not
#   install all needed dependencies.
#Pipfile.lock

# poetry
#   Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
#   This is especially recommended for binary packages to ensure reproducibility, and is more
#   commonly ignored for libraries.
#   https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock

# pdm
#   Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
#   pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
#   in version control.
#   https://pdm.fming.dev/#use-with-ide
.pdm.toml

# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/

# PyCharm
#  JetBrains specific template is maintained in a separate JetBrains.gitignore that can
#  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
#  and can be added to the global gitignore or merged into this file.  For a more nuclear
#  option (not recommended) you can uncomment the following to ignore the entire idea folder.
.idea/

# vscode
.vscode/

# keep configuration file
keep.yaml
.keep.yaml
providers.yaml
.vercel
keepstate.json

# keep single tenant id
e1faa321-35df-486b-8fa8-3601ee714011*

# sqlite db
*.sqlite3
state/*
.terraform*
examples/alerts/dd.yml
keep-ui/node_modules
keep-ui/node_modules/*

cov.xml
keep.db
keepdd.db
RANDOM_USER_ID
storage

# otel files
tempo-data/

# docs
docs/node_modules/

oauth2.cfg


scripts/automatic_extraction_rules.py

playwright_dump_*.html
playwright_dump_*.png
playwright_dump_*.txt
playwright_dump_*.json

ee/experimental/ai_temp/*
,e!ee/experimental/ai_temp/.gitkeep

oauth2.cfg
scripts/keep_slack_bot.py
*.db
providers_cache.json
providers_list.json
workflow-yaml-json-schema.json

tests/provision/*
!tests/provision/workflows*
grafana/*
!grafana/provisioning/
!grafana/dashboards/
keep/providers/grafana_provider/grafana/png/*
topology.sh
posthog.py


================================================
FILE: .pre-commit-config.yaml
================================================
repos:
  - repo: local
    hooks:
      - id: black
        name: black
        entry: black
        language: system
        types: [python]
        require_serial: true
      - id: end-of-file-fixer
        name: Fix End of Files
        entry: end-of-file-fixer
        language: system
        types: [text]
        stages: [commit, push, manual]
      - id: isort
        name: isort
        entry: isort
        require_serial: true
        language: system
        types_or: [cython, pyi, python]
        args: ["--filter-files", "--profile", "black"]
      - id: trailing-whitespace
        name: Trim Trailing Whitespace
        entry: trailing-whitespace-fixer
        language: system
        types: [text]
        stages: [commit, push, manual]
  - repo: https://github.com/astral-sh/ruff-pre-commit
    # Ruff version.
    rev: v0.1.6
    hooks:
      # Run the linter.
      - id: ruff
        args: [--fix]
  - repo: https://github.com/compilerla/conventional-pre-commit
    rev: v2.1.1
    hooks:
      - id: conventional-pre-commit
        stages: [commit-msg]
        args: [] # optional: list of Conventional Commits types to allow e.g. [feat, fix, ci, chore, test]
  - repo: https://github.com/pre-commit/mirrors-prettier
    rev: v3.0.3
    hooks:
      - id: prettier
        types_or:
          [javascript, jsx, ts, tsx, json, yaml, css, scss, html, markdown]
        args: [--write]


================================================
FILE: .python-version
================================================
3.11.1


================================================
FILE: CHANGELOG.md
================================================
# CHANGELOG
{% if context.history.unreleased | length > 0 %}

{# UNRELEASED #}
## Unreleased
{% for type_, commits in context.history.unreleased | dictsort %}
### {{ type_ | capitalize }}
{% for commit in commits %}{% if type_ != "unknown" %}
* {{ commit.commit.message.rstrip() }} ([`{{ commit.commit.hexsha[:7] }}`]({{ commit.commit.hexsha | commit_hash_url }}))
{% else %}
* {{ commit.commit.message.rstrip() }} ([`{{ commit.commit.hexsha[:7] }}`]({{ commit.commit.hexsha | commit_hash_url }}))
{% endif %}{% endfor %}{% endfor %}

{% endif %}

{# RELEASED #}
{% for version, release in context.history.released.items() %}
## {{ version.as_tag() }} ({{ release.tagged_date.strftime("%Y-%m-%d") }})
{% for type_, commits in release["elements"] | dictsort %}
### {{ type_ | capitalize }}
{% for commit in commits %}{% if type_ != "unknown" %}
* {{ commit.commit.message.rstrip() }} ([`{{ commit.commit.hexsha[:7] }}`]({{ commit.commit.hexsha | commit_hash_url }}))
{% else %}
* {{ commit.commit.message.rstrip() }} ([`{{ commit.commit.hexsha[:7] }}`]({{ commit.commit.hexsha | commit_hash_url }}))
{% endif %}{% endfor %}{% endfor %}{% endfor %}

================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to Keep
We love your input! We want to make contributing to this project as easy and transparent as possible, whether it's:

- Reporting a bug
- Discussing the current state of the code
- Submitting a fix
- Proposing new features
- Becoming a maintainer

## We Develop with Github
We use github to host code, to track issues and feature requests, as well as accept pull requests.

## We Use [Github Flow](https://guides.github.com/introduction/flow/index.html), So All Code Changes Happen Through Pull Requests
Pull requests are the best way to propose changes to the codebase (we use [Github Flow](https://guides.github.com/introduction/flow/index.html)). We actively welcome your pull requests:

1. Fork the repo and create your branch from `main`.
2. If you've added code that should be tested, add tests.
3. If you've changed APIs, update the documentation.
4. Ensure the test suite passes.
5. Make sure your code lints.
6. Issue that pull request!

## Any contributions you make will be under the MIT Software License
In short, when you submit code changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/) that covers the project. Feel free to contact the maintainers if that's a concern.

## Report bugs using Github's [issues](https://github.com/keephq/keep/issues)
We use GitHub issues to track public bugs. Report a bug by [opening a new issue](); it's that easy!

**Great Bug Reports** tend to have:

- A quick summary and/or background
- Steps to reproduce
  - Be specific!
  - Give sample code if you can.
- What you expected would happen
- What actually happens
- Notes (possibly including why you think this might be happening, or stuff you tried that didn't work)

People *love* thorough bug reports. I'm not even kidding.

## Use a Consistent Coding Style

Follow PEP8, use `black` for formatting and `isort` to sort imports.

## License
By contributing, you agree that your contributions will be licensed under its MIT License.

## References
This document was adapted from the open-source contribution guidelines for [Facebook's Draft](https://github.com/facebook/draft-js/blob/a9316a723f9e918afde44dea68b5f9f39b7d9b00/CONTRIBUTING.md)


================================================
FILE: LICENSE
================================================
Copyright (c) 2024 Keep

Portions of this software are licensed as follows:

* All content that resides under the "ee/" directory of this repository, if that directory exists, is licensed under the license defined in "ee/LICENSE".
* Content outside of the above mentioned directories or restrictions above is available under the "MIT" license as defined below.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
<div align="center">
    <img src="/assets/keep.png?raw=true" width="86">
</div>

<h1 align="center">The open-source AIOps and alert management platform</h1>

</br>

<div align="center">Single pane of glass, alert deduplication, enrichment, filtering and correlation, bi-directional integrations, workflows, dashboards.
</br>
</div>

<div align="center">
    <a href='http://makeapullrequest.com'>
      <img alt='PRs Welcome' src='https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=shields'/></a>
    <a href="https://slack.keephq.dev">
      <img src="https://img.shields.io/badge/Join-important.svg?color=4A154B&label=Slack&logo=slack&labelColor=334155&logoColor=f5f5f5" alt="Join Slack" /></a>
    <a href="https://github.com/keephq/keep/commits/main">
      <img alt="GitHub commit activity" src="https://img.shields.io/github/commit-activity/m/keephq/keep"/></a>
    <a href="https://codecov.io/gh/keephq/keep" >
        <img src="https://codecov.io/gh/keephq/keep/branch/main/graph/badge.svg?token=2VT6XYMRGS"/>
    </a>
</div>

<p align="center">
    <a href="https://docs.keephq.dev">Docs</a>
    ·
    <a href="https://platform.keephq.dev">Try it out</a>
    ·
    <a href="https://github.com/keephq/keep/issues/new?assignees=&labels=bug&template=bug_report.md&title=">Report Bug</a>
    ·
    <a href="https://www.keephq.dev/meet-keep">Book a Demo</a>
    ·
    <a href="https://www.keephq.dev">Website</a>
</p>

<div style="width: 100%; max-width: 800px; margin: 0 auto;">
    <img
        src="/assets/sneaknew.png?raw=true"
        style="width: 100%; height: auto; object-fit: contain;"
        alt="Sneak preview screenshot"
    >
</div>

<h1 align="center"></h1>

- 🔍 **Single pane of glass** - Best-in-class customizable UI for all your alerts and incidents
- 🛠️ **Swiss Army Knife for alerts** - Deduplication, correlation, filtering and enrichment
- 🔄 **Deep integrations** - Bi-directional syncs with monitoring tools, customizable workflows
- ⚡ **[Automation](#workflows)** - GitHub Actions for your monitoring tools
- 🤖 **AIOps 2.0** - AI-powered correlation and summarization

</br>

> See full [platform documentation](https://docs.keephq.dev).

</br>

## Supported Integrations

> View the full list in our [documentation](https://docs.keephq.dev/providers/documentation)

> Missing a provider? [Submit a new provider request](https://github.com/keephq/keep/issues/new?assignees=&labels=provider&projects=&template=new_provider_request.md&title=) and we'll add it quickly!

### AI Backends for Enrichments, Correlations and Incident Context Gathering

<table>
<tr>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/anthropic-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/anthropic-icon.png" alt="Anthropic"/><br/>
            Anthropic
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/openai-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/openai-icon.png" alt="OpenAI"/><br/>
            OpenAI
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/deepseek-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/deepseek-icon.png" alt="DeepSeek"/><br/>
            DeepSeek
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/ollama-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/ollama-icon.png" alt="Ollama"/><br/>
            Ollama
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/llamacpp-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/llamacpp-icon.png" alt="LlamaCPP"/><br/>
            LlamaCPP
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/grok-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/grok-icon.png" alt="Grok"/><br/>
            Grok
        </a>
    </td>
</tr>
<tr>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/gemini-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/gemini-icon.png" alt="Gemini"/><br/>
            Gemini
        </a>
    </td>
</tr>
</table>

### Observability Tools

<table>
<tr>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/appdynamics-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/appdynamics-icon.png" alt="AppDynamics"/><br/>
            AppDynamics
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/axiom-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/axiom-icon.png" alt="Axiom"/><br/>
            Axiom
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/azuremonitoring-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/azuremonitoring-icon.png" alt="Azure Monitoring"/><br/>
            Azure Monitoring
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/centreon-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/centreon-icon.png" alt="Centreon"/><br/>
            Centreon
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/checkmk-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/checkmk-icon.png" alt="Checkmk"/><br/>
            Checkmk
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/cilium-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/cilium-icon.png" alt="Cilium"/><br/>
            Cilium
        </a>
    </td>
</tr>
<tr>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/checkly-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/checkly-icon.png" alt="Checkly"/><br/>
            Checkly
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/cloudwatch-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/cloudwatch-icon.png" alt="CloudWatch"/><br/>
            CloudWatch
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/coralogix-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/coralogix-icon.png" alt="Coralogix"/><br/>
            Coralogix
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/dash0-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/dash0-icon.png" alt="Dash0"/><br/>
            Dash0
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/datadog-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/datadog-icon.png" alt="Datadog"/><br/>
            Datadog
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/dynatrace-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/dynatrace-icon.png" alt="Dynatrace"/><br/>
            Dynatrace
        </a>
    </td>
  </tr>
  <tr>
    <td align="center">
        <a href="https://docs.keephq.dev/providers/documentation/elastic-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/elastic-icon.png" alt="Elastic"/><br/>
            Elastic
        </a>
    </td>
    <td align="center">
        <a href="https://docs.keephq.dev/providers/documentation/gcpmonitoring-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/gcpmonitoring-icon.png" alt="GCP Monitoring"/><br/>
            GCP Monitoring
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/grafana-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/grafana-icon.png" alt="Grafana"/><br/>
            Grafana
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/grafana_loki-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/grafana_loki-icon.png" alt="Grafana Loki"/><br/>
            Grafana Loki
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/graylog-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/graylog-icon.png" alt="Graylog"/><br/>
            Graylog
        </a>
    </td>
    <td align="center" width="150">
    <a href="https://docs.keephq.dev/providers/documentation/icinga2-provider" target="_blank">
        <img width="40" src="keep-ui/public/icons/icinga2-icon.png" alt="Icinga2"/>
        <br/>
        Icinga2
    </a>
    </td>
  </tr>
  <tr>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/kibana-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/kibana-icon.png" alt="Kibana"/><br/>
            Kibana
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/libre_nms-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/libre_nms-icon.png" alt="LibreNMS"/><br/>
            LibreNMS
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/netbox-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/netbox-icon.png" alt="NetBox"/><br/>
            NetBox
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/netdata-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/netdata-icon.png" alt="Netdata"/><br/>
            Netdata
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/new-relic-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/newrelic-icon.png" alt="New Relic"/><br/>
            New Relic
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/opensearchserverless-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/opensearchserverless-icon.png" alt="OpenSearch Serverless"/><br/>
            OpenSearch Serverless
        </a>
    </td>

</tr>
<tr>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/parseable-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/parseable-icon.png" alt="Parseable"/><br/>
            Parseable
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/pingdom-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/pingdom-icon.png" alt="Pingdom"/><br/>
            Pingdom
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/prometheus-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/prometheus-icon.png" alt="Prometheus"/><br/>
            Prometheus
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/rollbar-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/rollbar-icon.png" alt="Rollbar"/><br/>
            Rollbar
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/sentry-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/sentry-icon.png" alt="Sentry"/><br/>
            Sentry
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/signalfx-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/signalfx-icon.png" alt="SignalFX"/><br/>
            SignalFX
        </a>
    </td>

</tr>
<tr>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/openobserve-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/openobserve-icon.png" alt="OpenObserve"/><br/>
            OpenObserve
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/site24x7-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/site24x7-icon.png" alt="Site24x7"/><br/>
          Site24x7
        </a>
  </td>
  <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/splunk-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/splunk-icon.png" alt="Splunk"/><br/>
          Splunk
        </a>
  </td>
  <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/statuscake-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/statuscake-icon.png" alt="StatusCake"/><br/>
          StatusCake
        </a>
  </td>
  <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/sumologic-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/sumologic-icon.png" alt="SumoLogic"/><br/>
          SumoLogic
        </a>
  </td>
  <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/thousandeyes-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/thousandeyes-icon.png" alt="SumoLogic"/><br/>
          ThousandEyes
        </a>
  </td>

</tr>
<tr>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/uptimekuma-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/uptimekuma-icon.png" alt="UptimeKuma"/><br/>
          UptimeKuma
        </a>
  </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/victorialogs-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/victorialogs-icon.png" alt="VictoriaLogs"/><br/>
          VictoriaLogs
        </a>
  </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/victoriametrics-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/victoriametrics-icon.png" alt="VictoriaMetrics"/><br/>
          VictoriaMetrics
        </a>
  </td>
  <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/wazuh-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/wazuh-icon.png" alt="Wazuh"/><br/>
          Wazuh
        </a>
  </td>
  <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/zabbix-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/zabbix-icon.png" alt="Zabbix"/><br/>
          Zabbix
        </a>
  </td>
</tr>
</table>

### Databases & Data Warehouses

<table>
<tr>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/bigquery-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/bigquery-icon.png" alt="BigQuery"/><br/>
            BigQuery
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/clickhouse-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/clickhouse-icon.png" alt="ClickHouse"/><br/>
            ClickHouse
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/databend-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/databend-icon.png" alt="Databend"/><br/>
            Databend
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/mongodb-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/mongodb-icon.png" alt="MongoDB"/><br/>
            MongoDB
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/mysql-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/mysql-icon.png" alt="MySQL"/><br/>
            MySQL
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/postgres-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/postgres-icon.png" alt="PostgreSQL"/><br/>
            PostgreSQL
        </a>
    </td>
</tr>
<tr>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/snowflake-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/snowflake-icon.png" alt="Snowflake"/><br/>
            Snowflake
        </a>
    </td>
</tr>
</table>

### Communication Platforms

<table>
<tr>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/discord" target="_blank">
            <img width="40" src="keep-ui/public/icons/discord-icon.png" alt="Discord"/><br/>
            Discord
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/google_chat-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/google_chat-icon.png" alt="Google Chat"/><br/>
            Google Chat
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/mailgun-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/mailgun-icon.png" alt="Mailgun"/><br/>
            Mailgun
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/mattermost-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/mattermost-icon.png" alt="Mattermost"/><br/>
            Mattermost
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/ntfy-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/ntfy-icon.png" alt="Ntfy.sh"/><br/>
            Ntfy.sh
        </a>
    </td>
  <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/pushover-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/pushover-icon.png" alt="Pushover"/><br/>
            Pushover
        </a>
  </td>
  <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/resend-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/resend-icon.png" alt="Resend"/><br/>
            Resend
        </a>
  </td>
</tr>
<tr>
  <td align="center" width="150">
      <a href="https://docs.keephq.dev/providers/documentation/sendgrid-provider" target="_blank">
          <img width="40" src="keep-ui/public/icons/sendgrid-icon.png" alt="SendGrid"/><br/>
          SendGrid
      </a>
  </td>
  <td align="center" width="150">
      <a href="https://docs.keephq.dev/providers/documentation/slack-provider" target="_blank">
          <img width="40" src="keep-ui/public/icons/slack-icon.png" alt="Slack"/><br/>
          Slack
      </a>
  </td>
  <td align="center" width="150">
      <a href="https://docs.keephq.dev/providers/documentation/smtp-provider" target="_blank">
          <img width="40" src="keep-ui/public/icons/smtp-icon.png" alt="SMTP"/><br/>
          SMTP
      </a>
  </td>
  <td align="center" width="150">
      <a href="https://docs.keephq.dev/providers/documentation/telegram-provider" target="_blank">
          <img width="40" src="keep-ui/public/icons/telegram-icon.png" alt="Telegram"/><br/>
          Telegram
      </a>
  </td>
  <td align="center" width="150">
      <a href="https://docs.keephq.dev/providers/documentation/twilio-provider" target="_blank">
          <img width="40" src="keep-ui/public/icons/twilio-icon.png" alt="Twilio"/><br/>
          Twilio
      </a>
  </td>
  <td align="center" width="150">
      <a href="https://docs.keephq.dev/providers/documentation/teams-provider" target="_blank">
          <img width="40" src="keep-ui/public/icons/teams-icon.png" alt="Teams"/><br/>
          Teams
      </a>
  </td>
  <td align="center" width="150">
      <a href="https://docs.keephq.dev/providers/documentation/zoom-provider" target="_blank">
          <img width="40" src="keep-ui/public/icons/zoom-icon.png" alt="Zoom"/><br/>
          Zoom
      </a>
  </td>
</tr>
<tr>
  <td align="center" width="150">
      <a href="https://docs.keephq.dev/providers/documentation/zoom_chat-provider" target="_blank">
          <img width="40" src="keep-ui/public/icons/zoom-icon.png" alt="Zoom Chat"/><br/>
          Zoom Chat
      </a>
  </td>
</tr>
</table>

### Incident Management

<table>
  <tr>
      <td align="center" width="150">
          <a href="https://docs.keephq.dev/providers/documentation/grafana_incident-provider" target="_blank">
              <img width="40" src="keep-ui/public/icons/grafana_incident-icon.png" alt="Grafana Incident"/><br/>
              Grafana Incident
          </a>
      </td>
      <td align="center" width="150">
          <a href="https://docs.keephq.dev/providers/documentation/grafana_oncall-provider" target="_blank">
              <img width="40" src="keep-ui/public/icons/grafana_oncall-icon.png" alt="Grafana OnCall"/><br/>
              Grafana OnCall
          </a>
      </td>
      <td align="center" width="150">
          <a href="https://docs.keephq.dev/providers/documentation/ilert-provider" target="_blank">
              <img width="40" src="keep-ui/public/icons/ilert-icon.png" alt="Ilert"/><br/>
              Ilert
          </a>
      </td>
      <td align="center" width="150">
          <a href="https://docs.keephq.dev/providers/documentation/incidentio-provider" target="_blank">
              <img width="40" src="keep-ui/public/icons/incidentio-icon.png" alt="Incident.io"/><br/>
              Incident.io
          </a>
      </td>
      <td align="center" width="150">
          <a href="https://docs.keephq.dev/providers/documentation/incidentmanager-provider" target="_blank">
              <img width="40" src="keep-ui/public/icons/incidentmanager-icon.png" alt="AWS Incident Manager"/><br/>
              AWS Incident Manager
          </a>
      </td>
      <td align="center" width="150">
          <a href="https://docs.keephq.dev/providers/documentation/opsgenie-provider" target="_blank">
              <img width="40" src="keep-ui/public/icons/opsgenie-icon.png" alt="OpsGenie"/><br/>
              OpsGenie
          </a>
      </td>
  </tr>
    <tr>
      <td align="center" width="150">
          <a href="https://docs.keephq.dev/providers/documentation/pagerduty-provider" target="_blank">
              <img width="40" src="keep-ui/public/icons/pagerduty-icon.png" alt="PagerDuty"/><br/>
              PagerDuty
          </a>
      </td>
      <td align="center" width="150">
          <a href="https://docs.keephq.dev/providers/documentation/pagertree-provider" target="_blank">
              <img width="40" src="keep-ui/public/icons/pagertree-icon.png" alt="Pagertree"/><br/>
              Pagertree
          </a>
      </td>
      <td align="center" width="150">
          <a href="https://docs.keephq.dev/providers/documentation/signl4-provider" target="_blank">
              <img width="40" src="keep-ui/public/icons/signl4-icon.png" alt="SINGL4"/><br/>
              SINGL4
          </a>
      </td>
      <td align="center" width="150">
          <a href="https://docs.keephq.dev/providers/documentation/squadcast-provider" target="_blank">
              <img width="40" src="keep-ui/public/icons/squadcast-icon.png" alt="Squadcast"/><br/>
              Squadcast
          </a>
      </td>
      <td align="center" width="150">
          <a href="https://docs.keephq.dev/providers/documentation/zenduty-provider" target="_blank">
              <img width="40" src="keep-ui/public/icons/zenduty-icon.png" alt="Zenduty"/><br/>
              Zenduty
          </a>
      </td>
      <td align="center" width="150">
          <a href="https://docs.keephq.dev/providers/documentation/flashduty-provider" target="_blank">
              <img width="40" src="keep-ui/public/icons/flashduty-icon.png" alt="Flashduty"/><br/>
              Flashduty
          </a>
      </td>
  </tr>
</table>

### Ticketing Tools

<table>
<tr>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/asana-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/asana-icon.png" alt="Asana"/><br/>
            Asana
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/github-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/github-icon.png" alt="GitHub"/><br/>
            GitHub
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/gitlab-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/gitlab-icon.png" alt="GitLab"/><br/>
            GitLab
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/jira-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/jira-icon.png" alt="Jira"/><br/>
            Jira
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/linear_provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/linear-icon.png" alt="Linear"/><br/>
            Linear
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/linearb-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/linearb-icon.png" alt="LinearB"/><br/>
            LinearB
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/microsoft-planner-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/microsoft-planner-icon.svg" alt="Microsoft Planner"/><br/>
            Microsoft Planner
        </a>
    </td>
</tr>
<tr>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/monday-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/monday-icon.png" alt="Monday"/><br/>
            Monday
        </a>
    </td>
  <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/redmine-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/redmine-icon.png" alt="Redmine"/><br/>
            Redmine
        </a>
  </td>
  <td align="center" width="150">
      <a href="https://docs.keephq.dev/providers/documentation/service-now-provider" target="_blank">
          <img width="40" src="keep-ui/public/icons/servicenow-icon.png" alt="ServiceNow"/><br/>
          ServiceNow
      </a>
  </td>
  <td align="center" width="150">
      <a href="https://docs.keephq.dev/providers/documentation/trello-provider" target="_blank">
          <img width="40" src="keep-ui/public/icons/trello-icon.png" alt="Trello"/><br/>
          Trello
      </a>
  </td>
  <td align="center" width="150">
      <a href="https://docs.keephq.dev/providers/documentation/youtrack-provider" target="_blank">
          <img width="40" src="keep-ui/public/icons/youtrack-icon.png" alt="YouTrack"/><br/>
          YouTrack
      </a>
  </td>
</tr>
</table>

### Container Orchestration Platforms

<table>
<tr>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/aks-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/aks-icon.png" alt="Azure AKS"/><br/>
            Azure AKS
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/argocd-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/argocd-icon.png" alt="ArgoCD"/><br/>
            ArgoCD
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/fluxcd-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/fluxcd-icon.png" alt="Flux CD"/><br/>
            Flux
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/gke-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/gke-icon.png" alt="GKE"/><br/>
            GKE
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/kubernetes-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/kubernetes-icon.png" alt="Kubernetes"/><br/>
            Kubernetes
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/openshift-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/openshift-icon.png" alt="OpenShift"/><br/>
            OpenShift
        </a>
    </td>
</tr>
</table>

### Data Enrichment

<table>
<tr>
<td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/bash-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/bash-icon.png" alt="Bash"/><br/>
            Bash
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/openai-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/openai-icon.png" alt="OpenAI"/><br/>
            OpenAI
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/python-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/python-icon.png" alt="Python"/><br/>
            Python
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/quickchart-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/quickchart-icon.png" alt="QuickChart"/><br/>
            QuickChart
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/ssh-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/ssh-icon.png" alt="SSH"/><br/>
            SSH
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/webhook-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/webhook-icon.png" alt="Webhook"/><br/>
            Webhook
        </a>
    </td>
</tr>
</table>

### Workflow Orchestration

<table>
<tr>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/airflow-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/airflow-icon.png" alt="Airflow"/><br/>
            Airflow
        </a>
    </td>
</tr>
</table>

### Queues

<table>
<tr>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/amazonsqs-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/amazonsqs-icon.png" alt="AmazonSQS"/><br/>
            Amazon SQS
        </a>
    </td>
    <td align="center" width="150">
        <a href="https://docs.keephq.dev/providers/documentation/kafka-provider" target="_blank">
            <img width="40" src="keep-ui/public/icons/kafka-icon.png" alt="Kafka"/><br/>
            Kafka
        </a>
    </td>
</tr>
</table>

## Workflows

Keep is GitHub Actions for your monitoring tools.

A Keep Workflow is a declarative YAML file that automates your alert and incident management. Each workflow consists of:

- **Triggers** - What starts the workflow (alerts, incidents, schedule or manual)
- **Steps** - Read or fetch data (enrichment, context)
- **Actions** - Execute operations (update tickets, send notifications, restart servers)

Here's a simple workflow that creates a Jira ticket for every `critical` alert from `sentry` for `payments` and `api` services.

For more workflows, see [here](https://github.com/keephq/keep/tree/main/examples/workflows).

```yaml
workflow:
  id: sentry-alerts
  description: create ticket alerts for critical alerts from sentry
  triggers:
    - type: alert
      # customize the filter to run only on critical alert from sentry
      filters:
        - key: source
          value: sentry
        - key: severity
          value: critical
        # regex to match specific services
        - key: service
          value: r"(payments|ftp)"
  actions:
    - name: send-slack-message-team-payments
      # if the alert is on the payments service, slack the payments team
      if: "'{{ alert.service }}' == 'payments'"
      provider:
        type: slack
        # control which Slack configuration you want to use
        config: " {{ providers.team-payments-slack }} "
        # customize the alert message with context from {{ alert }} or any other {{ step }}
        with:
          message: |
            "A new alert from Sentry: Alert: {{ alert.name }} - {{ alert.description }}
            {{ alert}}"
    - name: create-jira-ticket-oncall-board
      # control the workflow flow with "if" and "foreach" statements
      if: "'{{ alert.service }}' == 'ftp' and not '{{ alert.ticket_id }}'"
      provider:
        type: jira
        config: " {{ providers.jira }} "
        with:
          board_name: "Oncall Board"
          custom_fields:
            customfield_10201: "Critical"
          issuetype: "Task"
          # customize the summary
          summary: "{{ alert.name }} - {{ alert.description }} (created by Keep)"
          description: |
            "This ticket was created by Keep.
            Please check the alert details below:
            {code:json} {{ alert }} {code}"
          # enrich the alerts with more context. from now on, the alert will be assigned with the ticket id, type and url
          enrich_alert:
            - key: ticket_type
              value: jira
            - key: ticket_id
              value: results.issue.key
            - key: ticket_url
              value: results.ticket_url
```

## Enterprise Ready

- **Developer First** - Modern REST APIs, native SDKs, and comprehensive documentation for seamless integration
- **[Enterprise Security](https://docs.keephq.dev/deployment/authentication/overview)** - Full authentication support (SSO, SAML, OIDC, LDAP) with granular access control (RBAC, ABAC) and team management
- **Flexible Deployment** - Deploy on-premises or in air-gapped environments with cloud-agnostic architecture
- **[Production Scale](https://docs.keephq.dev/deployment/stress-testing)** - High availability, performance-tested infrastructure supporting horizontal scaling for enterprise workloads

## Getting Started

> Need help? Can't find your environment listed? Reach out on Slack and we'll help you quickly.

Keep can run in various environments and configurations. The easiest way to start is with Keep's Docker Compose.

- Running Keep [locally](https://docs.keephq.dev/development/getting-started).
- Running Keep on [Kubernetes](https://docs.keephq.dev/deployment/kubernetes/installation).
- Running Keep with [Docker](https://docs.keephq.dev/deployment/docker).
- Running Keep on [AWS ECS](https://docs.keephq.dev/deployment/ecs).
- Running Keep on [OpenShift](https://docs.keephq.dev/deployment/kubernetes/openshift).

## 🫵 Keepers

### Top Contributors

A special thanks to our top contributors who help us make Keep great. You are more than awesome!

- [Furkan](https://github.com/pehlicd)
- [Asharon](https://github.com/asharonbaltazar)

Want to become a top contributor? Join our Slack and DM Tal, Shahar, or Furkan.

### Contributors

Thank you for contributing and continuously making <b>Keep</b> better, <b>you're awesome</b> 🫶

<a href="https://github.com/keephq/keep/graphs/contributors">
  <img src="https://contrib.rocks/image?repo=keephq/keep" />
</a>


================================================
FILE: docker/Dockerfile.api
================================================
FROM python:3.13.5-alpine as base

# Install bash and runtime dependencies for grpc
RUN apk add --no-cache bash libstdc++

ENV PYTHONFAULTHANDLER=1 \
    PYTHONHASHSEED=random \
    PYTHONUNBUFFERED=1

# THIS IS FOR DEBUGGING PURPOSES
# RUN apt-get update && \
#     apt-get install -y --no-install-recommends \
#     iproute2 \
#    net-tools \
#    procps && \
#    rm -rf /var/lib/apt/lists/*

RUN addgroup -g 1000 keep && \
    adduser -u 1000 -G keep -s /bin/sh -D keep
WORKDIR /app

FROM base as builder

# Install build dependencies for Alpine
RUN apk add --no-cache \
    gcc \
    g++ \
    musl-dev \
    libffi-dev \
    openssl-dev \
    postgresql-dev \
    mysql-client \
    build-base \
    linux-headers \
    git

ENV PIP_DEFAULT_TIMEOUT=100 \
    PIP_DISABLE_PIP_VERSION_CHECK=1 \
    PIP_NO_CACHE_DIR=1 \
    POETRY_VERSION=1.3.2

RUN pip install "poetry==$POETRY_VERSION"
RUN python -m venv /venv
COPY pyproject.toml poetry.lock ./
RUN poetry export -f requirements.txt --output requirements.txt --without-hashes --only main && \
    /venv/bin/python -m pip install --upgrade -r requirements.txt && \
    pip uninstall -y poetry
COPY keep keep
COPY ee keep/ee
COPY examples examples
COPY keep-ui/public/icons/unknown-icon.png unknown-icon.png
RUN /venv/bin/pip install --use-deprecated=legacy-resolver . && \
    rm -rf /root/.cache/pip && \
    find /venv -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true && \
    find /venv -type f -name "*.pyc" -delete 2>/dev/null || true

FROM base as final
ENV PATH="/venv/bin:${PATH}"
ENV VIRTUAL_ENV="/venv"
ENV EE_PATH="ee"
COPY --from=builder /venv /venv
COPY --from=builder /app/examples /examples
COPY --from=builder /app/unknown-icon.png unknown-icon.png
# as per Openshift guidelines, https://docs.openshift.com/container-platform/4.11/openshift_images/create-images.html#use-uid_create-images
RUN chgrp -R 0 /app && chmod -R g=u /app && \
    chown -R keep:keep /app && \
    chown -R keep:keep /venv
USER keep

ENTRYPOINT ["/venv/lib/python3.13/site-packages/keep/entrypoint.sh"]

CMD ["gunicorn", "keep.api.api:get_app", "--bind" , "0.0.0.0:8080" , "--workers", "4" , "-k" , "uvicorn.workers.UvicornWorker", "-c", "/venv/lib/python3.13/site-packages/keep/api/config.py", "--preload"]


================================================
FILE: docker/Dockerfile.cli
================================================
FROM python:3.11.6-slim as base

ENV PYTHONFAULTHANDLER=1 \
    PYTHONHASHSEED=random \
    PYTHONUNBUFFERED=1

WORKDIR /app

FROM base as builder

ENV PIP_DEFAULT_TIMEOUT=100 \
    PIP_DISABLE_PIP_VERSION_CHECK=1 \
    PIP_NO_CACHE_DIR=1 \
    POETRY_VERSION=1.3.2

RUN pip install "poetry==$POETRY_VERSION"
RUN python -m venv /venv
COPY . .
RUN poetry build && /venv/bin/pip install --use-deprecated=legacy-resolver dist/*.whl

FROM base as final

ENV PATH="/venv/bin:${PATH}"
ENV VIRTUAL_ENV="/venv"
COPY --from=builder /venv /venv


================================================
FILE: docker/Dockerfile.dev.api
================================================
FROM python:3.11.6-slim as base

ENV PYTHONFAULTHANDLER=1 \
    PYTHONHASHSEED=random \
    PYTHONUNBUFFERED=1

WORKDIR /app

# Creating a virtual environment and installing dependencies
ENV PIP_DEFAULT_TIMEOUT=100 \
    PIP_DISABLE_PIP_VERSION_CHECK=1 \
    PIP_NO_CACHE_DIR=1 \
    POETRY_VERSION=1.3.2

RUN pip install "poetry==$POETRY_VERSION"
RUN python -m venv /venv
COPY pyproject.toml ./
RUN . /venv/bin/activate && poetry install --no-root

COPY keep keep
COPY ee keep/ee

# Setting the virtual environment path
ENV PYTHONPATH="/app:${PYTHONPATH}"
ENV PATH="/venv/bin:${PATH}"
ENV VIRTUAL_ENV="/venv"
ENV POSTHOG_DISABLED="true"

ENTRYPOINT ["/app/keep/entrypoint.sh"]

CMD ["gunicorn", "keep.api.api:get_app", "--bind" , "0.0.0.0:8080" , "--workers", "1" , "-k" , "uvicorn.workers.UvicornWorker", "-c", "./keep/api/config.py", "--reload"]


================================================
FILE: docker/Dockerfile.dev.ui
================================================
# Use node alpine as it's a small node image
FROM node:alpine

# Create the directory on the node image
# where our Next.js app will live
RUN mkdir -p /app

# Set /app as the working directory
WORKDIR /app

# Copy package.json and package-lock.json
# to the /app working directory
COPY keep-ui/package*.json /app/

# Copy the rest of our Next.js folder into /app
COPY ./keep-ui/ /app

# Install dependencies in /app
RUN npm install
# Install next globally and create a symlink
RUN npm install -g next
RUN ln -s /usr/local/lib/node_modules/next/dist/bin/next /usr/local/bin/next || echo "next binary already linked to bin"
# Ensure port 3000 is accessible to our system
EXPOSE 3000

CMD ["npm", "run", "dev"]


================================================
FILE: docker/Dockerfile.ui
================================================
FROM node:20-alpine AS base

# Install dependencies only when needed
FROM base AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat
WORKDIR /app

# Install dependencies based on the preferred package manager
COPY package.json package-lock.json ./
RUN npm ci  --noproxy registry.npmjs.org --maxsockets 1


# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

# Next.js collects completely anonymous telemetry data about general usage.
# Learn more here: https://nextjs.org/telemetry
# Uncomment the following line in case you want to disable telemetry during the build.
ENV NEXT_TELEMETRY_DISABLED 1

# If using npm comment out above and use below instead
ENV API_URL http://localhost:8080
RUN NODE_OPTIONS=--max-old-space-size=8192  npm run build


# Production image, copy all the files and run next
FROM base AS runner
ARG GIT_COMMIT_HASH=local
ARG KEEP_VERSION=local
ARG KEEP_INCLUDE_SOURCES=false

WORKDIR /app
# Inject the git commit hash into the build
# This is being injected from the build script
ENV GIT_COMMIT_HASH=${GIT_COMMIT_HASH}
ENV KEEP_VERSION=${KEEP_VERSION}
ENV KEEP_INCLUDE_SOURCES=${KEEP_INCLUDE_SOURCES}



ENV NODE_ENV production
# Uncomment the following line in case you want to disable telemetry during runtime.
ENV NEXT_TELEMETRY_DISABLED 1

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public

# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
COPY entrypoint.sh /app/entrypoint.sh

# as per Openshift guidelines, https://docs.openshift.com/container-platform/4.11/openshift_images/create-images.html#use-uid_create-images
RUN chgrp -R 0 /app && chmod -R g=u /app
USER nextjs

EXPOSE 3000

ENV PORT 3000
ENV POSTHOG_KEY=phc_muk9qE3TfZsX3SZ9XxX52kCGJBclrjhkP9JxAQcm1PZ
ENV POSTHOG_HOST=https://ingest.keephq.dev
ENV PUSHER_HOST=localhost
ENV PUSHER_PORT=6001
ENV PUSHER_APP_KEY=keepappkey
ENV NEXT_PUBLIC_SENTRY_DSN=https://0d4d59e3105ffe8afa27dcb95a222009@o4505515398922240.ingest.us.sentry.io/4508258058764288


ENTRYPOINT ["/app/entrypoint.sh"]


================================================
FILE: docker-compose-with-arq.yml
================================================
services:
  keep-frontend:
    extends:
      file: docker-compose.common.yml
      service: keep-frontend-common
    image: us-central1-docker.pkg.dev/keephq/keep/keep-ui
    environment:
      - AUTH_TYPE=NO_AUTH
      - API_URL=http://keep-backend:8080
    volumes:
      - ./state:/state
    depends_on:
      - keep-backend

  keep-backend:
    extends:
      file: docker-compose.common.yml
      service: keep-backend-common
    image: us-central1-docker.pkg.dev/keephq/keep/keep-api
    environment:
      - AUTH_TYPE=NO_AUTH
      - REDIS=true
      - REDIS_HOST=keep-arq-redis
      - REDIS_PORT=6379
    volumes:
      - ./state:/state
    depends_on:
      - keep-arq-redis

  keep-websocket-server:
    extends:
      file: docker-compose.common.yml
      service: keep-websocket-server-common

  keep-arq-redis:
    image: redis/redis-stack
    ports:
      - "6379:6379"
      - "8081:8001"

  keep-arq-dashboard:
    image: us-central1-docker.pkg.dev/keephq/keep/keep-arq-dashboard
    ports:
      - "8082:8000"
    entrypoint:
        - "uvicorn"
        - "--host"
        - "0.0.0.0"
        - "arq_dashboard:app"
    environment:
      - ARQ_DASHBOARD_REDIS_URL=redis://keep-arq-redis:6379


================================================
FILE: docker-compose-with-auth.yml
================================================
services:
  keep-frontend:
    extends:
      file: docker-compose.common.yml
      service: keep-frontend-common
    image: us-central1-docker.pkg.dev/keephq/keep/keep-ui
    environment:
      - AUTH_TYPE=DB
      - NEXTAUTH_SECRET=verysecretkey
      - API_URL=http://keep-backend:8080
    volumes:
      - ./state:/state
    depends_on:
      - keep-backend

  keep-backend:
    extends:
      file: docker-compose.common.yml
      service: keep-backend-common
    image: us-central1-docker.pkg.dev/keephq/keep/keep-api
    environment:
      - AUTH_TYPE=DB
      - KEEP_JWT_SECRET=verysecretkey
      - KEEP_DEFAULT_USERNAME=keep
      - KEEP_DEFAULT_PASSWORD=keep
    volumes:
      - ./state:/state

  keep-websocket-server:
    extends:
      file: docker-compose.common.yml
      service: keep-websocket-server-common


================================================
FILE: docker-compose-with-otel.yaml
================================================
services:
  loki:
    image: grafana/loki:latest
    profiles:
      - otel

    ports:
      - "3100:3100"
    command: ["-config.file=/etc/loki/local-config.yaml"]

  tempo:
    image: grafana/tempo:latest
    profiles:
      - otel
    command: ["-config.file=/etc/tempo.yaml"]
    volumes:
      - ./otel-shared/tempo.yaml:/etc/tempo.yaml
      - ./tempo-data:/tmp/tempo
    ports:
      - "14268:14268" # jaeger ingest
      - "3200:3200" # tempo
      - "9095:9095" # tempo grpc
      - "4317:4317" # otlp grpc
      - "4318:4318" # otlp http
      - "9411:9411" # zipkin

  prometheus:
    image: prom/prometheus:latest
    profiles:
      - otel

    command:
      - --config.file=/etc/prometheus.yaml
      - --web.enable-remote-write-receiver
      - --enable-feature=exemplar-storage
    volumes:
      - ./otel-shared/prometheus.yaml:/etc/prometheus.yaml
    ports:
      - "9090:9090"

  alertmanager:
    image: prom/alertmanager
    profiles:
      - otel

    container_name: alertmanager
    volumes:
      - ./otel-shared/alertmanager.yml:/etc/alertmanager/alertmanager.yml
    command:
      - "--config.file=/etc/alertmanager/alertmanager.yml"

  grafana:
    image: grafana/grafana:10.0.3
    profiles:
      - otel

    depends_on:
      - loki
      - tempo
      - prometheus
    volumes:
      - ./otel-shared/grafana-datasources.yaml:/etc/grafana/provisioning/datasources/datasources.yaml
    environment:
      - GF_AUTH_ANONYMOUS_ENABLED=true
      - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
      - GF_AUTH_DISABLE_LOGIN_FORM=false
      - GF_FEATURE_TOGGLES_ENABLE=traceqlEditor
    ports:
      - "3001:3000"

  # OpenTelemetry collector. Make sure you set USERID and GOOGLE_APPLICATION_CREDENTIALS
  # environment variables for your container to authenticate correctly
  otel-collector:
    image: otel/opentelemetry-collector-contrib:0.81.0
    profiles:
      - otel

    ports:
      - "9100:9100"
    depends_on:
      - tempo
      - loki
    volumes:
      - ./otel-shared/otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml

  keep-frontend-dev:
    extends:
      file: docker-compose.common.yml
      service: keep-frontend-common
    environment:
      - API_URL=http://keep-backend-dev:8080
    build:
      dockerfile: docker/Dockerfile.dev.ui
    volumes:
      - ./keep-ui:/app
      - /app/node_modules
      - /app/.next
    depends_on:
      - keep-backend-dev

  keep-backend-dev:
    extends:
      file: docker-compose.common.yml
      service: keep-backend-common
    build:
      dockerfile: docker/Dockerfile.dev.api
    environment:
      - OTEL_SERVICE_NAME=keephq
      - OTLP_ENDPOINT=http://otel-collector:4317
      - METRIC_OTEL_ENABLED=true
    volumes:
      - .:/app
      - ./state:/state

  keep-websocket-server:
    extends:
      file: docker-compose.common.yml
      service: keep-websocket-server-common

  log_collector:
    image: timberio/vector:0.32.2-debian
    profiles:
      - otel
    volumes:
      - ./otel-shared/vector.toml:/etc/vector/vector.toml
      - /var/run/docker.sock:/var/run/docker.sock

volumes:
  certs:
    driver: local
  esdata01:
    driver: local
  kibanadata:
    driver: local

  db_data:


================================================
FILE: docker-compose.common.yml
================================================
services:
  keep-frontend-common:
    ports:
      - "3000:3000"
    environment:
      - NEXTAUTH_SECRET=secret
      - NEXTAUTH_URL=http://localhost:3000
      - NEXT_PUBLIC_API_URL=http://localhost:8080
      - POSTHOG_KEY=phc_muk9qE3TfZsX3SZ9XxX52kCGJBclrjhkP9JxAQcm1PZ
      - POSTHOG_HOST=https://ingest.keephq.dev
      - NEXT_PUBLIC_SENTRY_DSN=https://0d4d59e3105ffe8afa27dcb95a222009@o4505515398922240.ingest.us.sentry.io/4508258058764288
      - PUSHER_HOST=localhost
      - PUSHER_PORT=6001
      - PUSHER_APP_KEY=keepappkey

  keep-backend-common:
    ports:
      - "8080:8080"
    environment:
      - PORT=8080
      - SECRET_MANAGER_TYPE=FILE
      - SECRET_MANAGER_DIRECTORY=/state
      - DATABASE_CONNECTION_STRING=sqlite:////state/db.sqlite3?check_same_thread=False
      - OPENAI_API_KEY=$OPENAI_API_KEY
      - PUSHER_APP_ID=1
      - PUSHER_APP_KEY=keepappkey
      - PUSHER_APP_SECRET=keepappsecret
      - PUSHER_HOST=keep-websocket-server
      - PUSHER_PORT=6001
      - USE_NGROK=false

  keep-websocket-server-common:
    image: quay.io/soketi/soketi:1.4-16-debian
    ports:
      - "6001:6001"
      - "9601:9601"
    environment:
      - SOKETI_USER_AUTHENTICATION_TIMEOUT=3000
      - SOKETI_DEBUG=1
      - SOKETI_DEFAULT_APP_ID=1
      - SOKETI_DEFAULT_APP_KEY=keepappkey
      - SOKETI_DEFAULT_APP_SECRET=keepappsecret


================================================
FILE: docker-compose.dev.yml
================================================
services:
  keep-frontend-dev:
    extends:
      file: docker-compose.common.yml
      service: keep-frontend-common
    environment:
      - API_URL=http://keep-backend-dev:8080
      - SENTRY_DISABLED=true
    build:
      dockerfile: docker/Dockerfile.dev.ui
    volumes:
      - ./keep-ui:/app
      - /app/node_modules
      - /app/.next
    depends_on:
      - keep-backend-dev

  keep-backend-dev:
    extends:
      file: docker-compose.common.yml
      service: keep-backend-common
    build:
      dockerfile: docker/Dockerfile.dev.api
    volumes:
      - .:/app
      - ./state:/state

  keep-websocket-server:
    extends:
      file: docker-compose.common.yml
      service: keep-websocket-server-common


================================================
FILE: docker-compose.yml
================================================
services:
  keep-frontend:
    extends:
      file: docker-compose.common.yml
      service: keep-frontend-common
    image: us-central1-docker.pkg.dev/keephq/keep/keep-ui
    environment:
      - AUTH_TYPE=NO_AUTH
      - API_URL=http://keep-backend:8080
    volumes:
      - ./state:/state
    depends_on:
      - keep-backend

  keep-backend:
    extends:
      file: docker-compose.common.yml
      service: keep-backend-common
    image: us-central1-docker.pkg.dev/keephq/keep/keep-api
    environment:
      - AUTH_TYPE=NO_AUTH
      - PROMETHEUS_MULTIPROC_DIR=/tmp/prometheus
      - KEEP_METRICS=true
    volumes:
      - ./state:/state

  keep-websocket-server:
    extends:
      file: docker-compose.common.yml
      service: keep-websocket-server-common

  grafana:
    image: grafana/grafana:latest
    profiles:
      - grafana
    ports:
      - "3001:3000"
    volumes:
      - ./grafana:/var/lib/grafana
      - ./grafana/provisioning:/etc/grafana/provisioning
      - ./grafana/dashboards:/etc/grafana/dashboards
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=admin
      - GF_USERS_ALLOW_SIGN_UP=false
    depends_on:
      - prometheus

  prometheus:
    image: prom/prometheus:latest
    profiles:
      - grafana
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
    command:
      - "--config.file=/etc/prometheus/prometheus.yml"
    depends_on:
      - keep-backend


================================================
FILE: docs/README.md
================================================
How to run docs locally:

```
npm i -g mintlify
mintlify dev
```

Read more: https://mintlify.com/docs/development


================================================
FILE: docs/alertevaluation/examples/victoriametricsmulti.mdx
================================================
---
title: "VictoriaMetrics Multi Alert Example"
---

This example demonstrates a simple CPU usage multi-alert based on a metric:

```yaml
workflow:
  # Unique identifier for this workflow
  id: query-victoriametrics-multi
  # Display name shown in the UI
  name: victoriametrics-multi-alert-example
  # Brief description of what this workflow does
  description: victoriametrics
  triggers:
    # This workflow can be triggered manually from the UI
    - type: manual
  steps:
    # Query VictoriaMetrics for CPU metrics
    - name: victoriametrics-step
      provider:
        # Use the VictoriaMetrics provider configuration
        config: "{{ providers.vm }}"
        type: victoriametrics
        with:
          # Query that returns the sum of CPU usage for each job
          # Example response:
          # [
          #   {'metric': {'job': 'victoriametrics'}, 'value': [1737808021, '0.022633333333333307']},
          #   {'metric': {'job': 'vmagent'}, 'value': [1737808021, '0.009299999999999998']}
          # ]
          query: sum(rate(process_cpu_seconds_total)) by (job)
          queryType: query

  actions:
    # Create an alert in Keep based on the query results
    - name: create-alert
      provider:
        type: keep
        with:
          # Only create alert if CPU usage is above threshold
          if: "{{ value.1 }} > 0.01 "
          # Alert must persist for 1 minute
          for: 1m
          # Use job label to create unique fingerprint for each alert
          fingerprint_fields:
            - labels.job
          alert:
            # Alert name includes the specific job
            name: "High CPU Usage on {{ metric.job }}"
            description: "CPU usage is high on the VM (created from VM metric)"
            # Set severity based on CPU usage thresholds:
            # > 0.9 = critical
            # > 0.7 = warning
            # else = info
            severity: '{{ value.1 }} > 0.9 ? "critical" : {{ value.1 }} > 0.7 ? "warning" : "info"'
            labels:
              # Job label is required for alert fingerprinting
              job: "{{ metric.job }}"
              # Additional context labels
              environment: production
              app: myapp
              service: api
              team: devops
              owner: alice

```


================================================
FILE: docs/alertevaluation/examples/victoriametricssingle.mdx
================================================
---
title: "VictoriaMetrics Single Alert Example"
---

This example demonstrates a simple CPU usage alert based on a metric:

```yaml
# This workflow queries VictoriaMetrics metrics and creates alerts based on CPU usage
workflow:
  # Unique identifier for this workflow
  id: query-victoriametrics
  # Display name shown in the UI
  name: victoriametrics-alert-example
  # Brief description of what this workflow does
  description: Monitors CPU usage metrics from VictoriaMetrics and creates alerts when thresholds are exceeded

  # Define how the workflow is triggered
  triggers:
    - type: manual # Can be triggered manually from the UI

  # Steps to execute in order
  steps:
    - name: victoriametrics-step
      provider:
        # Use VictoriaMetrics provider config defined in providers.vm
        config: "{{ providers.vm }}"
        type: victoriametrics
        with:
          # Query average CPU usage rate
          query: avg(rate(process_cpu_seconds_total))
          queryType: query

  # Actions to take based on the query results
  actions:
    - name: create-alert
      provider:
        type: keep
        with:
          # Create alert if CPU usage exceeds threshold
          if: "{{ value.1 }} > 0.0040"
          alert:
            name: "High CPU Usage"
            description: "[Single] CPU usage is high on the VM (created from VM metric)"
            # Set severity based on CPU usage thresholds
            severity: '{{ value.1 }} > 0.9 ? "critical" : {{ value.1 }} > 0.7 ? "warning" : "info"'
            # Alert labels for filtering and routing
            labels:
              environment: production
              app: myapp
              service: api
              team: devops
              owner: alice
```


================================================
FILE: docs/alertevaluation/overview.mdx
================================================
---
title: "Overview"
---

The Keep Alert Evaluation Engine is a flexible system that enables you to create alerts based on any data source and define evaluation rules. Unlike traditional monitoring solutions that are tied to specific metrics, Keep's engine allows you to combine data from multiple sources and apply complex logic to determine when and how alerts should be triggered.

## Core Features

### Generic Data Source Support
- Query any data source (databases, APIs, metrics systems)
- Combine multiple data sources in a single alert rule
- Apply custom transformations to the data

### Flexible Alert Evaluation
- Define custom conditions using templated expressions
- Support for complex boolean logic and mathematical operations
- State management for alert transitions (pending->firing->resolved)
- Deduplication and alert instance tracking

### Customizable Alert Definition
- Full control over alert metadata (name, description, severity)
- Dynamic labels based on evaluation context
- Template support for all alert fields
- Custom fingerprinting for alert grouping

## Core Components

### Alert States
- **Pending**: Initial state when alert condition is met (relevant only if `for` supplied)
- **Firing**: Active alert that has met its duration condition
- **Resolved**: Alert that is no longer active

### Alert Rule Components
1. **Data Collection**: Query steps to gather data from any source
2. **Condition (`if`)**: Expression that determines when to create/update an alert
3. **Duration (`for`)**: Optional time period the condition must be true before firing
4. **Alert Definition**: Complete control over how the alert looks and behaves:
   - Name and description
   - Severity levels
   - Labels for routing
   - Custom fields and annotations

### State Management
- **Fingerprinting**: Unique identifier for alert deduplication and state tracking
- **Keep-Firing**: Control how long alerts remain active
- **State Transitions**: Rules for how alerts move between states

## Examples
The following examples demonstrate different ways to use the alert evaluation engine:

- [Single Metric Alert](/alertevaluation/examples/victoriametricssingle) - Basic example showing metrics-based alerting
- [Multiple Metrics Alert](/alertevaluation/examples/victoriametricsmulti) - Advanced example with multiple alert instances


================================================
FILE: docs/alerts/actionmenu.mdx
================================================
---
title: "Action Menu"
---

The Action Menu in Keep provides quick access to common actions that can be performed on alerts. This menu enables teams to efficiently manage and interact with alerts directly from the table.

<Frame width="100" height="200">
  <img height="10" src="/images/alert_table_menu_1.png" />
</Frame>

### (1) Run Workflow
Trigger predefined workflows directly from the Action Menu. This allows automation of actions such as escalating alerts or notifying specific teams.

### (2) Create a New Workflow
Quickly create a new workflow tailored to the selected alert. This is useful for handling unique cases that require a custom response.

### (3) View Alert History
Access the full history of the alert, including changes to its status, comments, and any actions performed. This provides a clear timeline of the alert's lifecycle.

### (4) Manually Enrich Alert
Add custom metadata or details to an alert manually. This can include additional context or information that assists with resolution.

### (5) Self Assign
Assign the selected alert to yourself. This is ideal for team members who are taking ownership of specific alerts.

### (6) View Alert
Open the alert details in the sidebar or dedicated alert view for a deeper dive into its metadata and context.

### (7) Source-Specific Actions
Perform actions that are specific to the source of the alert. For example, linking directly to the monitoring tool or executing source-specific workflows.

### (8) Dismiss Alert
Mark the alert as dismissed to indicate that no further action is required. This helps in managing and decluttering the alert table.

### (9) Change Status
Update the status of the alert (e.g., from "firing" to "acknowledged"). This keeps the team informed about the current state of the alert.

---


================================================
FILE: docs/alerts/overview.mdx
================================================
---
title: "Overview"
---

**Alert Management** empowers teams to effectively manage, monitor, and act on critical alerts.

With a robust and user-friendly interface, Keep allows users to gain deep insights into their alerts, filter through large volumes of data, and take swift actions to maintain system health.

<Frame width="100" height="200">
  <img height="10" src="/images/alert_table_1.png" />
</Frame>

Everything related with Alert Management can be customized:

1. **Alert table** - view and manage the alerts.
2. **Search Bar** - use CEL to filter alerts which can be saved as "Customized Presets".
3. **Facets** - slice and dice alerts.
4. **Columns and Time** - customize columns and theme for your preset.


================================================
FILE: docs/alerts/presets.mdx
================================================
---
title: "Customized Presets"
---


<Tip>

You can think of a preset like a "Slack Channel" for your alerts - a logical container to follow only alerts that matter for you.

</Tip>

With Keep's introduction of CEL (Common Expression Language) for alert filtering, users gain the flexibility to define more complex and precise alert filtering logic.

This feature allows the creation of customizable filters using CEL expressions to refine alert visibility based on specific criteria.

## How It Works

1. **CEL Expression Creation**: Users craft CEL expressions that define the filtering criteria for alerts.
2. **Preset Definition**: These expressions can be saved as presets for easy application to different alert streams.
3. **Alert Filtering**: When applied, the CEL expressions evaluate each alert against the defined criteria, filtering the alert stream in real-time.


## Creating a CEL Expression

There are two ways of creating a CEL expression in Keep
### Manually creating CEL query

Use the [CEL Language Definition](https://github.com/google/cel-spec/blob/master/doc/langdef.md) documentation to better understand the capabilities of the Common Expression Language
This is an example of how to query all the alerts that came from `Sentry`
<Frame width="100" height="200">
  <img height="10" src="/images/presets/valid-sentry-cel.png" />
</Frame>
If the CEL syntax you typed in is invalid, an error message will show up (in this case, we used invalid `''` instead of `""`):
<Frame width="100" height="200">
  <img height="10" src="/images/presets/invalid-sentry-cel.png" />
</Frame>

### Importing from an SQL query

1. Click on the "Import from SQL" button
<Frame width="100" height="200">
  <img height="10" src="/images/presets/import-from-sql.png" />
</Frame>
2. Write/Paste your SQL query and hit the "Convert to CEL" button
<Frame width="100" height="200">
  <img height="10" src="/images/presets/convert-to-cel.png" />
</Frame>
Which in turn will generate and apply a valid CEL query:
<Frame width="100" height="200">
  <img height="10" src="/images/presets/converted-sql-to-cel.png" />
</Frame>

## Save Presets

You can save your CEL queries into a `Preset` using the "Save current filter as a view" button
<Frame width="100" height="200">
  <img height="10" src="/images/presets/save-preset.png" />
</Frame>
You can name your `Preset` and configure whether it is "Private" (only the creating user will see this Preset) or account-wide available.
<Frame width="100" height="200">
  <img height="10" src="/images/presets/save-preset-modal.png" />
</Frame>
The `Preset` will then be created and available for you to quickly navigate and used
<Frame width="100" height="200">
  <img height="10" src="/images/presets/preset-created.png" />
</Frame>

## Practical Example

For instance, a user could create a CEL expression to filter alerts by severity and source, such as `severity == 'critical' && service.contains('database')`, ensuring only critical alerts from database services are displayed.


## Best Practices

- **Specificity in Expressions**: Craft expressions that precisely target the desired alerts to avoid filtering out relevant alerts.
- **Presets Management**: Regularly review and update your presets to align with evolving alerting needs.
- **Testing Expressions**: Before applying, test CEL expressions to ensure they correctly filter the desired alerts.

## Useful Links
- [Common Expression Language](https://github.com/google/cel-spec?tab=readme-ov-file)
- [CEL Language Definition](https://github.com/google/cel-spec/blob/master/doc/langdef.md)


================================================
FILE: docs/alerts/sidebar.mdx
================================================
---
title: "Alert Sidebar"
---

The Alert Sidebar in Keep provides a detailed view of a selected alert, offering in-depth context and information to aid in alert management and resolution. This feature is designed to give users a comprehensive understanding of the alert without leaving the main interface.

<Frame width="100" height="200">
  <img height="10" src="/images/alert_table_sidebar.png" />
</Frame>

### (1) Alert Name
Displays the name of the alert, which typically summarizes the issue or event being reported. This is the primary identifier for the alert.

### (2) Alert Related Service
Shows the service associated with the alert. This helps teams quickly understand which part of the infrastructure or application is affected.

### (3) Alert Source
Indicates the source of the alert, such as the monitoring tool or system that generated it (e.g., Prometheus, Datadog). This provides context on where the alert originated.

### (4) Alert Description
A detailed description of the alert, including specifics about the issue. This section helps provide a deeper understanding of what triggered the alert.

### (5) Alert Fingerprint
A unique identifier for the alert. The fingerprint is used to correlate alerts and track their lifecycle across systems.

### (6) Alert Timeline
Displays a chronological history of the alert, including when it was created, acknowledged, updated, or resolved. The timeline provides insights into how the alert has been managed.

### (7) Alert Topology View
Offers a visual representation of the alert's impact on the system's topology. This view helps identify affected components and their relationships to other parts of the infrastructure.

---


================================================
FILE: docs/alerts/sound.mdx
================================================
---
title: "Sound Notifications"
---

Sound notifications ensure you never miss important updates or alerts.

## How It Works
1. **Preset Notifications**: Mark a preset as "noisy," and any alert linked to it will play a sound. Alternatively, set individual alerts as `isNoisy=true` to trigger sounds through linked presets.
2. **Real-Time Alerts**: With WebSocket enabled, alerts arrive instantly. The server notifies the browser, which retrieves and processes new alerts immediately.

## Who Hears Notifications?
Users with Keep open in their browser and the noisy preset visible in their navigation bar. Presets can be filtered to control notifications.

### Customizing
1. **Change the Default Sound**: Replace the `alert.mp3` file with a custom audio file of your choice.

---

================================================
FILE: docs/alerts/table.mdx
================================================
---
title: "Alert Table"
---

The Alert Table is the central interface for viewing and managing alerts in Keep. It provides a comprehensive view of all alerts with powerful filtering, sorting, and interaction capabilities.

<Frame width="100" height="200">
  <img height="10" src="/images/alert_table_table_1.png" />
</Frame>

### (1) Columns
Columns in the alert table can be customized to display the most relevant data. Users can select which columns to display and reorder them using drag-and-drop functionality.

<Frame width="100" height="200">
  <img height="10" src="/images/alert_table_table_2.png" />
</Frame>


### (2) Alert Bulk Action
Easily select one or more alerts for bulk actions. Actions include options like "assign to incident," "dismiss," or other available workflows.

<Frame width="100" height="200">
  <img height="10" src="/images/alert_table_table_3.png" />
</Frame>

### (3) Alert Actions Menu
The actions menu provides quick access to various operations for each alert, such as linking to incidents, creating tickets, or escalating.

<Frame width="100" height="200">
  <img height="10" src="/images/alert_table_table_4.png" />
</Frame>

### (4) Alert Link
Each alert includes a badge that links directly to the original alert in the monitoring tool. Clicking this badge opens the alert in its source system for further investigation.

<Frame width="100" height="200">
  <img height="10" src="/images/alert_table_table_5.png" />
</Frame>

### (5) Alert Ticket
You can asign ticket to alert. If an alert is associated with a ticket, a ticket badge will be displayed. Clicking on this badge navigates directly to the assigned ticket in the ticketing tool.

<Frame width="100" height="200">
  <img height="10" src="/images/alert_table_table_8.png" />
</Frame>

### (6) Alert Comment
Users can add comments to any alert to provide additional context or share insights with team members. This improves collaboration and ensures all relevant information is available.

<Frame width="100" height="200">
  <img height="10" src="/images/alert_table_table_9.png" />
</Frame>

### (7) Alert Related Workflows
View and trigger related workflows for an alert directly from the table. This allows seamless integration with predefined processes like escalation, suppression, or custom automation.

<Frame width="100" height="200">
  <img height="10" src="/images/alert_table_table_7.png" />
</Frame>


### (8) Sorting
The table supports sorting by any column using the "sort" icon. This makes it easy to prioritize or organize alerts based on specific criteria.

<Frame width="100" height="200">
  <img height="10" src="/images/alert_table_table_sort.gif" />
</Frame>

---


================================================
FILE: docs/applications/github.mdx
================================================
---
title: "GitHub Application"
sidebarTitle: "GitHub"
description: "The Keep GitHub Application is a powerful tool that enhances your workflow by monitoring file changes under the parent `.keep/` directory in your repositories' pull requests. It automates the process of generating AI-generated alerts from plain English and allows you to seamlessly deploy these alerts to your provider using comments."
---

## Getting Started

To start using the Keep GitHub Application, follow these simple steps:

1. Sign up and log in to the **[Keep's platform](https://platform.keephq.dev)**.
2. Install the **Keep GitHub Application** either through the onboarding screen or by visiting **[this link](https://github.com/apps/keephq)**. The installation process is straightforward and user-friendly.

   <Frame>
     <img src="/images/github-app-install.png" />
   </Frame>

3. Connect your preferred provider, such as Datadog, by linking it to Keep's platform. This step allows Keep to seamlessly generate and deploy alerts to your chosen provider.

   <Frame>
     <img src="/images/connect-provider.png" />
   </Frame>

4. You are now ready to go! The Keep GitHub Application is successfully integrated into your GitHub workflow.

## How does it work?

The Keep GitHub Application operates seamlessly in the background, ensuring that you stay informed about relevant changes in your repositories. Whenever a pull request is opened or updated, the application monitors the files under the .keep/ directory.

Once a change is detected, the GitHub application sends an HTTP request to Keep's API smart AI layer. The AI layer analyzes the content of the changed files and together with context from the provider (existing alerts, sample logs, etc.) generates an alert based on the user provided plain English description. The AI-powered alert generation ensures accuracy and relevance.

After the alert is generated, the Keep GitHub Application automatically comments the alert on the respective file within the pull request. This allows you, as the user, to conveniently review and verify the generated alert.

If the generated alert meets your requirements and is ready to be deployed, you can simply leave a comment on the file. The comment should include one of the predefined emojis, such as 🚀 or 🆗 (refer to the ["Deploying Alerts with Emojis"](#deploying-alerts-with-emojis) section). The Keep GitHub Application recognizes these emojis as commands to proceed with the deployment process.

This intuitive workflow streamlines the alert generation and deployment process, providing you with a seamless experience and allowing you to focus on the core aspects of your project.

## Monitoring Files Under .keep/ Directory

The Keep GitHub Application actively monitors the files residing within the `.keep/` directory located at the parent level of your repository. Any changes or updates made to these files will trigger the alert generation process. This allows you to focus on the essential aspects of your project while ensuring that relevant changes are promptly identified and acted upon.

## Alert File Structure

Each file under the `.keep/` directory represents a single alert. The structure of an alert file follows the YAML format. Below is an example of an alert file:

```yaml title=alert-example.yaml
# The alert text in plain English
alert: |
  Count the error rate (4xx-5xx) this service has in the last 10 minutes.
  Alert when the threshold is above 5% out of total requests.
  Send a Slack message to the #alerts-playground channel and include all the context you have"

# The provider you've previously connected and want this alert to be generated for
provider: datadog
# You can use this to override Keep's managed API and have the GitHub application
# use the API that you run locally (using the NGROK URL)
# api_url: https://OVERRIDE-KEEP-MANAGED-API
```

The alert file consists of the following components:

1. **Alert Text**: This section contains the plain English description of the alert. Write a clear and concise explanation of the conditions or criteria that should trigger the alert. You can include any relevant context to facilitate understanding and resolution.

2. **Provider**: Specify the provider to which you want the alert to be generated. This ensures that the alert seamlessly integrates with your existing monitoring and notification infrastructure. In the example above, the alert is configured to be generated for Datadog.

3. **API Override**: Optionally, you can include the api_url field to override Keep's managed API. This allows you to use your locally hosted API for advanced customization and integration purposes.

<Accordion title="ngrok">
  **ngrok?**

Imagine you have a secret hideout in your backyard, but you don't want anyone to know where it is. So, you build a tunnel from your hideout to a tree in your friend's backyard. This way, you can go into the tunnel in your yard and magically come out at the tree in your friend's yard.

Now, let's say you have a cool website or a game that you want to show your friend, but it's running on your computer at home. Your friend is far away and can't come to your house. So, you need a way to show them your website or game over the internet.

This is where ngrok comes in! Ngrok is like a magical tunnel, just like the one you built in your backyard. It creates a secure connection between your computer and the internet. It gives your computer a special address that people can use to reach your website or game, even though it's on your computer at home.

When you start ngrok, it opens up a tunnel between your computer and the internet. It assigns a special address to your computer, like a secret door to your website or game. When your friend enters that address in their web browser, it's as if they're walking through the tunnel and reaching your website or game on your computer.

So, ngrok is like a magical tunnel that helps you share your website or game with others over the internet, just like the secret tunnel you built to reach your friend's backyard!

**How to start Keep with ngrok**

ngrok is Controlled with the `USE_NGROK` environment variable.<br />
Simply run Keep's API using the following command to start with ngrok: `USE_NGROK=true keep api`

{" "}
<Note>
  `USE_NGROK` is enabled by default when running with `docker-compose`
</Note>

**How to obtain ngrok URL?**

When `USE_NGROK` is set, Keep will start with ngrok in the background. <br />
You can find your private ngrok URL looking for this log line "`ngrok tunnel`":

    ```json
    {
        "asctime": "0000-00-00 00:00:00,000",
        "message": "ngrok tunnel: https://fab5-213-57-123-130.ngrok.io",
        ...
    }
    ```

The URL (https://fab5-213-57-123-130.ngrok.io in the example above) is a publicly accessible URL to your Keep API service running locally. <br />

{" "}
<Note>
  You can check that the ngrok tunnel is working properly by sending a simple
  HTTP GET request to `/healthcheck` Try: `curl -v
  https://fab5-213-57-123-130.ngrok.io/healthcheck` in our example.
</Note>

</Accordion>

## Deploying Alerts with Emojis

To deploy an alert to the specified provider, you can simply leave a comment on the respective file using the 🚀 or 🆗 emojis. The Keep GitHub Application recognizes these emojis as commands and will initiate the deployment process accordingly. This streamlined approach ensures a smooth and intuitive experience when deploying alerts.

For example, by leaving a comment with the 🚀 emoji, you can signal the Keep GitHub Application to deploy the alert to the specified provider (Datadog in our example above).

<Frame>
  <img src="/images/first-alert.yaml.png" />
</Frame>

The Keep GitHub Application will either mark the comment with 👍 meaning the alert was successfully deployed or 👎 and another comment with the failure reason in case the alert was not deployed.

<Info>
  Keep GitHub Application has a retry mechanism that automatically tries to fix
  the alert in case it was not successfully deployed to the provider. If the
  alert that is deployed is different from the originally generated one, Keep
  Github Application will comment the updated one once again.
</Info>


================================================
FILE: docs/authentication/okta.md
================================================
# Okta Integration Guide

This document provides comprehensive information about the Okta integration in Keep, including configuration, deployment, maintenance, and testing.

## Overview

Keep supports Okta as an authentication provider, enabling:
- Single Sign-On (SSO) via Okta
- JWT token validation with JWKS
- User and group management through Okta
- Role-based access control
- Token refresh capabilities

## Environment Variables

### Backend Environment Variables

| Variable | Description | Example |
|----------|-------------|---------|
| `AUTH_TYPE` | Set to `"okta"` to enable Okta authentication | `okta` |
| `OKTA_DOMAIN` | Your Okta domain | `company.okta.com` |
| `OKTA_API_TOKEN` | Admin API token for Okta management | `00aBcD3f4GhIJkl5m6NoPQr` |
| `OKTA_ISSUER` | The issuer URL for your Okta application | `https://company.okta.com/oauth2/default` |
| `OKTA_CLIENT_ID` | Client ID of your Okta application | `0oa1b2c3d4e5f6g7h8i9j` |
| `OKTA_CLIENT_SECRET` | Client Secret of your Okta application | `abcd1234efgh5678ijkl9012` |
| `OKTA_AUDIENCE` | (Optional) The audience for token validation | `api://keep` |

### Frontend Environment Variables

| Variable | Description | Example |
|----------|-------------|---------|
| `AUTH_TYPE` | Set to `"OKTA"` to enable Okta authentication | `OKTA` |
| `OKTA_CLIENT_ID` | Client ID of your Okta application | `0oa1b2c3d4e5f6g7h8i9j` |
| `OKTA_CLIENT_SECRET` | Client Secret of your Okta application | `abcd1234efgh5678ijkl9012` |
| `OKTA_ISSUER` | The issuer URL for your Okta application | `https://company.okta.com/oauth2/default` |
| `OKTA_DOMAIN` | Your Okta domain | `company.okta.com` |

## Okta Configuration

### Creating an Okta Application

1. Sign in to your Okta Admin Console
2. Navigate to **Applications** > **Applications**
3. Click **Create App Integration**
4. Select **OIDC - OpenID Connect** as the Sign-in method
5. Choose **Web Application** as the Application type
6. Click **Next**

### Application Settings

1. **Name**: Enter a name for your application (e.g., "Keep")
2. **Grant type**: Select Authorization Code
3. **Sign-in redirect URIs**: Enter your app's callback URL, e.g., `https://your-keep-domain.com/api/auth/callback/okta`
4. **Sign-out redirect URIs**: Enter your app's sign-out URL, e.g., `https://your-keep-domain.com/signin`
5. **Assignments**:
   - **Skip group assignment for now** or assign to appropriate groups
6. Click **Save**

### Create API Token

1. Navigate to **Security** > **API**
2. Select the **Tokens** tab
3. Click **Create Token**
4. Name your token (e.g., "Keep Integration")
5. Copy the generated token value (this will be your `OKTA_API_TOKEN`)

### Configure OIDC Claims (Optional but Recommended)

1. Navigate to your application
2. Go to the **Sign On** tab
3. Under **OpenID Connect ID Token**, click **Edit**
4. Add custom claims:
   - `keep_tenant_id`: The tenant ID in Keep
   - `keep_role`: The user's role in Keep

## Deployment Instructions

### Docker Deployment

Add the required environment variables to your docker-compose file or Kubernetes deployment:

```yaml
environment:
  - AUTH_TYPE=okta
  - OKTA_DOMAIN=your-company.okta.com
  - OKTA_API_TOKEN=your-api-token
  - OKTA_ISSUER=https://your-company.okta.com/oauth2/default
  - OKTA_CLIENT_ID=your-client-id
  - OKTA_CLIENT_SECRET=your-client-secret
```

### Next.js Frontend

Configure environment variables in your `.env.local` file:

```
AUTH_TYPE=OKTA
OKTA_CLIENT_ID=your-client-id
OKTA_CLIENT_SECRET=your-client-secret
OKTA_ISSUER=https://your-company.okta.com/oauth2/default
OKTA_DOMAIN=your-company.okta.com
```

### Vercel Deployment

Add the environment variables in your Vercel project settings.

## User and Group Management

### Users

The system automatically maps Okta users to Keep users. Key mappings:

- Okta email → Keep email
- Okta firstName → Keep name
- Okta groups → Keep groups
- Custom claim `keep_role` → Keep role (defaults to "user" if not specified)

### Groups

Groups in Okta are synchronized with Keep. Groups with names starting with `keep_` are treated as roles.

### Roles

Roles are implemented as Okta groups with the prefix `keep_`. For example:
- `keep_admin` → Admin role in Keep
- `keep_user` → User role in Keep

## Authentication Flow

1. User accesses Keep application
2. User is redirected to Okta login page
3. After successful authentication, Okta returns an ID token and access token
4. Keep validates the token using Okta's JWKS endpoint
5. Keep extracts user information and permissions from the token
6. When tokens expire, Keep automatically refreshes them using the refresh token

## Token Refresh

The refresh token flow is handled automatically by the application:

1. The system detects when an access token is about to expire
2. It uses the refresh token to obtain a new access token from Okta
3. The new token is stored and used for subsequent requests

## Testing Strategies

### Unit Tests

1. **AuthVerifier Tests**: Test token validation with mock tokens
   ```python
   def test_okta_verify_bearer_token():
       # Create a mock token with the expected claims
       # Initialize the OktaAuthVerifier
       # Verify the token is validated correctly
   ```

2. **IdentityManager Tests**: Test user and group management
   ```python
   def test_okta_create_user():
       # Mock Okta API responses
       # Test creating a user
       # Verify the correct API calls are made
   ```

### Integration Tests

1. **End-to-End Authentication Flow**:
   - Create a test user in Okta
   - Attempt to log in to the application
   - Verify successful authentication

2. **Token Refresh Test**:
   - Obtain an access token and refresh token
   - Wait for token expiration
   - Verify token refresh occurs automatically

3. **Role-Based Access Control**:
   - Create users with different roles
   - Verify access to different endpoints based on roles

### Load Tests

1. **Token Validation Performance**:
   - Simulate multiple concurrent requests with tokens
   - Measure response time and system load
   - Verify JWKS caching is working correctly

2. **User Management Scaling**:
   - Test with a large number of users and groups
   - Measure performance of group and user operations

## Troubleshooting

### Common Issues

1. **Invalid Token Errors**:
   - Check that `OKTA_ISSUER` matches the issuer in your Okta application
   - Verify that token signing algorithm (RS256) is supported
   - Check for clock skew between your server and Okta

2. **API Request Failures**:
   - Verify that `OKTA_API_TOKEN` is valid and has sufficient permissions
   - Check rate limiting on Okta API

3. **User Not Found**:
   - Verify that the user exists in Okta
   - Check user status (active/deactivated)

### Debugging

1. Enable debug logging:
   ```
   AUTH_DEBUG=true
   ```

2. Check Okta API logs in the Okta Admin Console

## Maintenance Considerations

### Token Rotation

- Rotate the `OKTA_API_TOKEN` periodically for security
- Update the application with the new token without downtime

### JWKS Caching

- The implementation caches JWKS keys for 24 hours
- Adjust the cache duration if needed based on key rotation policy

### Custom Claims

- When adding new custom claims, update both Okta configuration and code

### API Rate Limits

- Be aware of Okta API rate limits
- Implement retry logic for rate limit errors

## Code Structure

### Backend Components

- **`keep/identitymanager/identity_managers/okta/okta_authverifier.py`**: Handles JWT validation with JWKS
- **`keep/identitymanager/identity_managers/okta/okta_identitymanager.py`**: Manages users, groups, and roles via Okta API

### Frontend Components

- **`auth.config.ts`**: NextAuth.js configuration for Okta
- **`authenticationType.ts`**: Defines Okta as an authentication type

## Security Considerations

1. **Secure Storage of Secrets**:
   - Store `OKTA_CLIENT_SECRET` and `OKTA_API_TOKEN` securely
   - Never commit secrets to version control

2. **Token Validation**:
   - Always validate tokens with proper signature verification
   - Verify token audience and issuer

3. **Scoped API Tokens**:
   - Use the principle of least privilege for API tokens

## Future Improvements

1. **Enhanced Group Mapping**:
   - Implement more sophisticated group-to-role mappings
   - Support nested groups in Okta

2. **Custom Authorization Servers**:
   - Support multiple Okta authorization servers
   - Allow tenant-specific authorization servers

3. **Custom Scope Handling**:
   - Better integrate Okta scopes with Keep permissions

## Support and Resources

- [Okta Developer Documentation](https://developer.okta.com/docs/reference/)
- [NextAuth.js Okta Provider Documentation](https://next-auth.js.org/providers/okta)
- [JWT Debugging Tools](https://jwt.io/) 

================================================
FILE: docs/cli/commands/alert-enrich.mdx
================================================
---
sidebarTitle: "keep alert enrich"
---

Enrich an alert.

## Usage

```
Usage: keep alert enrich [OPTIONS] [PARAMS]...
```

## Options


## CLI Help

```
Usage: keep alert enrich [OPTIONS] [PARAMS]...

  Enrich an alert.

Options:
  --fingerprint TEXT  The fingerprint of the alert to enrich.  [required]
  --help              Show this message and exit.
```


================================================
FILE: docs/cli/commands/alert-get.mdx
================================================
---
sidebarTitle: "keep alert get"
---

Get an alert.

## Usage

```
Usage: keep alert get [OPTIONS] FINGERPRINT
```

## Options


## CLI Help

```
Usage: keep alert get [OPTIONS] FINGERPRINT

Options:
  --help  Show this message and exit.
```


================================================
FILE: docs/cli/commands/alert-list.mdx
================================================
---
sidebarTitle: "keep alert list"
---

List alerts.

## Usage

```
Usage: keep alert list [OPTIONS]
```

## Options
* `filter`:
  * Type: STRING
  * Default: `none`
  * Usage: `--filter
-f`

  Filter alerts based on specific attributes. E.g., --filter source=datadog


* `export`:
  * Type: Path
  * Default: `none`
  * Usage: `--export`

  Export alerts to a specified JSON file.


* `help`:
  * Type: BOOL
  * Default: `false`
  * Usage: `--help`

  Show this message and exit.



## CLI Help

```
Usage: keep alert list [OPTIONS]

  List alerts.

Options:
  -f, --filter TEXT  Filter alerts based on specific attributes. E.g.,
                     --filter source=datadog

  --export PATH      Export alerts to a specified JSON file.
  --help             Show this message and exit.
```


================================================
FILE: docs/cli/commands/cli-alert.mdx
================================================

# cli alert

Manage alerts.

## Usage

```
Usage: cli alert [OPTIONS] COMMAND [ARGS]...
```

## Options
* `help`:
  * Type: BOOL
  * Default: `false`
  * Usage: `--help`

  Show this message and exit.



## CLI Help

```
Usage: cli alert [OPTIONS] COMMAND [ARGS]...

  Manage alerts.

Options:
  --help  Show this message and exit.

Commands:
  enrich  Enrich an alert.
  get
  list    List alerts.
```


================================================
FILE: docs/cli/commands/cli-api.mdx
================================================
---
title: "api"
sidebarTitle: "keep api"
---

Start the API.

## Usage

```
Usage: keep api [OPTIONS]
```

## Options
* `multi_tenant`:
  * Type: BOOL
  * Default: `false`
  * Usage: `--multi-tenant`

  Enable multi-tenant mode


* `help`:
  * Type: BOOL
  * Default: `false`
  * Usage: `--help`

  Show this message and exit.



## CLI Help

```
Usage: keep api [OPTIONS]

  Start the API.

Options:
  --multi-tenant  Enable multi-tenant mode
  --help          Show this message and exit.
```


================================================
FILE: docs/cli/commands/cli-config-new.mdx
================================================
---
sidebarTitle: "keep config new"
---

Create new config.

## Usage

```
Usage: keep config new [OPTIONS]...
```

## Options
* `interactive`:
  * Type: BOOL
  * Default: `True`
  * Usage: `--interactive`

  Create config interactively.

* `url`:
  * Type: STRING
  * Default: `http://localhost:8080`
  * Usage: `--url`

  The URL of the Keep backend server.

* `api-key`:
  * Type: STRING
  * Default: ``
  * Usage: `--api-key`

  The api key for authenticating over keep.

* `help`:
  * Type: BOOL
  * Default: `false`
  * Usage: `--help`

  Show this message and exit.



## CLI Help

```
Usage: keep config new [OPTIONS]

  create new config.

Options:
  -u, --url TEXT      The url of the keep api
  -a, --api-key TEXT  The api key for keep
  -i, --interactive   Interactive mode creating keep config (default True)
  --help              Show this message and exit.
```


================================================
FILE: docs/cli/commands/cli-config-show.mdx
================================================
---
sidebarTitle: "keep config show"
---

Show keep configuration.

## Usage

```
Usage: keep config show [OPTIONS]...
```

## Options
* `help`:
  * Type: BOOL
  * Default: `false`
  * Usage: `--help`

  Show this message and exit.



## CLI Help

```
Usage: keep config show [OPTIONS]

  show the current config.

Options:
  --help  Show this message and exit.
```


================================================
FILE: docs/cli/commands/cli-config.mdx
================================================
---
title: "config"
sidebarTitle: "keep config"
---

Set keep configuration.

## Usage

```
Usage: keep config [OPTIONS] COMMAND [ARGS]...
```

## Options
* `help`:
  * Type: BOOL
  * Default: `false`
  * Usage: `--help`

  Show this message and exit.



## CLI Help

```
Usage: keep config [OPTIONS] COMMAND [ARGS]...

  Manage the config.

Options:
  --help  Show this message and exit.

Commands:
  new   create new config.
  show  show the current config.
```


================================================
FILE: docs/cli/commands/cli-provider.mdx
================================================

# cli provider

Manage providers.

## Usage

```
Usage: cli provider [OPTIONS] COMMAND [ARGS]...
```

## Options
* `help`:
  * Type: BOOL
  * Default: `false`
  * Usage: `--help`

  Show this message and exit.



## CLI Help

```
Usage: cli provider [OPTIONS] COMMAND [ARGS]...

  Manage providers.

Options:
  --help  Show this message and exit.

Commands:
  connect
  delete
  list     List providers.
```


================================================
FILE: docs/cli/commands/cli-run.mdx
================================================
---
title: "run"
sidebarTitle: "keep run"
---

Run the alert.

## Usage

```
Usage: keep run [OPTIONS]
```

## Options
* `alerts_directory`:
  * Type: STRING
  * Default: `none`
  * Usage: `--alerts-directory
--alerts-file
-af`

  The path to the alert yaml/alerts directory


* `alert_url`:
  * Type: STRING
  * Default: `none`
  * Usage: `--alert-url
-au`

  A url that can be used to download an alert yaml NOTE: This argument is mutually exclusive with alerts_directory


* `interval`:
  * Type: INT
  * Default: `0`
  * Usage: `--interval
-i`

  When interval is set, Keep will run the alert every INTERVAL seconds


* `providers_file`:
  * Type: STRING
  * Default: `providers.yaml`
  * Usage: `--providers-file
-p`

  The path to the providers yaml


* `tenant_id`:
  * Type: STRING
  * Default: `singletenant`
  * Usage: `--tenant-id
-t`

  The tenant id


* `api_key`:
  * Type: STRING
  * Default: `none`
  * Usage: `--api-key`

  The API key for keep's API


* `api_url`:
  * Type: STRING
  * Default: `https://s.keephq.dev`
  * Usage: `--api-url`

  The URL for keep's API


* `help`:
  * Type: BOOL
  * Default: `false`
  * Usage: `--help`

  Show this message and exit.



## CLI Help

```
Usage: keep run [OPTIONS]

  Run the alert.

Options:
  -af, --alerts-directory, --alerts-file PATH
                                  The path to the alert yaml/alerts directory
  -au, --alert-url TEXT           A url that can be used to download an alert
                                  yaml NOTE: This argument is mutually
                                  exclusive with alerts_directory

  -i, --interval INTEGER          When interval is set, Keep will run the
                                  alert every INTERVAL seconds

  -p, --providers-file PATH       The path to the providers yaml
  -t, --tenant-id TEXT            The tenant id
  --api-key TEXT                  The API key for keep's API
  --api-url TEXT                  The URL for keep's API
  --help                          Show this message and exit.
```


================================================
FILE: docs/cli/commands/cli-version.mdx
================================================
---
title: "version"
sidebarTitle: "keep version"
---

Get the library version.

## Usage

```
Usage: keep version [OPTIONS]
```

## Options
* `help`:
  * Type: BOOL
  * Default: `false`
  * Usage: `--help`

  Show this message and exit.



## CLI Help

```
Usage: keep version [OPTIONS]

  Get the library version.

Options:
  --help  Show this message and exit.
```


================================================
FILE: docs/cli/commands/cli-whoami.mdx
================================================
---
title: "whoami"
sidebarTitle: "keep whoami"
---

Verify the api key auth.

## Usage

```
Usage: keep whoami [OPTIONS]
```

## Options
* `help`:
  * Type: BOOL
  * Default: `false`
  * Usage: `--help`

  Show this message and exit.



## CLI Help

```
Usage: keep whoami [OPTIONS]

  Verify the api key auth.

Options:
  --help  Show this message and exit.
```


================================================
FILE: docs/cli/commands/cli-workflow.mdx
================================================

# cli workflow

Manage workflows.

## Usage

```
Usage: cli workflow [OPTIONS] COMMAND [ARGS]...
```

## Options
* `help`:
  * Type: BOOL
  * Default: `false`
  * Usage: `--help`

  Show this message and exit.



## CLI Help

```
Usage: cli workflow [OPTIONS] COMMAND [ARGS]...

  Manage workflows.

Options:
  --help  Show this message and exit.

Commands:
  apply  Apply a workflow.
  list   List workflows.
  run    Run a workflow with a specified ID and fingerprint.
  runs   Manage workflows executions.
```


================================================
FILE: docs/cli/commands/cli.mdx
================================================

# cli

Run Keep CLI.

## Usage

```
Usage: cli [OPTIONS] COMMAND [ARGS]...
```

## Options
* `verbose`:
  * Type: IntRange(0, None)
  * Default: `0`
  * Usage: `--verbose
-v`

  Enable verbose output.


* `json`:
  * Type: BOOL
  * Default: `false`
  * Usage: `--json
-j`

  Enable json output.


* `keep_config`:
  * Type: STRING
  * Default: `keep.yaml`
  * Usage: `--keep-config
-c`

  The path to the keep config file (default keep.yaml)


* `help`:
  * Type: BOOL
  * Default: `false`
  * Usage: `--help`

  Show this message and exit.



## CLI Help

```
Usage: cli [OPTIONS] COMMAND [ARGS]...

  Run Keep CLI.

Options:
  -v, --verbose           Enable verbose output.
  -j, --json              Enable json output.
  -c, --keep-config TEXT  The path to the keep config file (default keep.yaml)
  --help                  Show this message and exit.

Commands:
  alert     Manage alerts.
  api       Start the API.
  config    Get the config.
  provider  Manage providers.
  run       Run a workflow.
  version   Get the library version.
  whoami    Verify the api key auth.
  workflow  Manage workflows.
```


================================================
FILE: docs/cli/commands/extraction-create.mdx
================================================
---
sidebarTitle: "keep extraction create"
---

Create a extraction rule.

## Usage

```
Usage: keep extraction create [OPTIONS]
```

## Options

* `name`
  * Type: STRING
  * Default: ``
  * Usage: `--name <extraction-name>`

  The name of the extraction.

* `description`
  * Type: STRING
  * Default: ``
  * Usage: `--description <extraction-description>`

  The description of the extraction.

* `priority`
  * Type: INTEGER RANGE
  * Default: `0`
  * Usage: `--priority <priority>`

  The priority of the extraction, higher priority means this rule will execute first. `0<=x<=100`.

* `pre`
  * Type: BOOL
  * Default: `false`
  * Usage: `--pre <pre>`

  Whether this rule should be applied before or after the alert is standardized

* `attribute`
  * Type: STRING
  * Default: ``
  * Usage: `--attribute <extraction-attribute>`

  Event attribute name to extract from.

* `regex`
  * Type: STRING
  * Default: ``
  * Usage: `--attribute <regex-regex>`

  The regex rule to extract by. Regex format should be like python regex pattern for group matching.

* `condition`
  * Type: STRING
  * Default: ``
  * Usage: `--condition <condition-attribute>`

  CEL based condition.

* `help`:
  * Type: BOOL
  * Default: `false`
  * Usage: `--help`

  Show this message and exit.

## CLI Help

```
Usage: cli.py extraction create [OPTIONS]

  Create a extraction rule.

Options:
  -n, --name TEXT               The name of the extraction.  [required]
  -d, --description TEXT        The description of the extraction.
  -p, --priority INTEGER RANGE  The priority of the extraction, higher
                                priority means this rule will execute first.
                                [0<=x<=100]
  --pre BOOLEAN                 Whether this rule should be applied before or
                                after the alert is standardized.
  -a, --attribute TEXT          Event attribute name to extract from.
                                [required]
  -r, --regex TEXT              The regex rule to extract by. Regex format
                                should be like python regex pattern for group
                                matching.  [required]
  -c, --condition TEXT          CEL based condition.  [required]
  --help                        Show this message and exit.
```


================================================
FILE: docs/cli/commands/extraction-delete.mdx
================================================
---
sidebarTitle: "keep extraction delete"
---

Delete an extraction with a specified ID.

## Usage

```
Usage: keep extraction delete [OPTIONS]
```

## Options

* `extraction-id`
  * Type: STRING
  * Default: ``
  * Usage: `--extraction-id <extraction-id>`

  The ID of the extraction to delete.

* `help`:
  * Type: BOOL
  * Default: `false`
  * Usage: `--help`

  Show this message and exit.



## CLI Help

```
Usage: cli.py extraction delete [OPTIONS]

  Delete a extraction with a specified ID.

Options:
  --extraction-id INTEGER  The ID of the extraction to delete.  [required]
  --help                   Show this message and exit.
```


================================================
FILE: docs/cli/commands/extractions-list.mdx
================================================
---
sidebarTitle: "keep extraction list"
---

List extractions.

## Usage

```
Usage: keep extraction list [OPTIONS]
```

List mappings.

## Options

* `help`:
  * Type: BOOL
  * Default: `false`
  * Usage: `--help`

  Show this message and exit.

## CLI Help

```
Usage: cli.py extraction list [OPTIONS]

  List extractions.

Options:
  --help  Show this message and exit.
```


================================================
FILE: docs/cli/commands/mappings-create.mdx
================================================
---
sidebarTitle: "keep mappings create"
---

Create a mapping rule.

## Usage

```
Usage: keep mappings create [OPTIONS]
```

## Options

* `name`
  * Type: STRING
  * Default: ``
  * Usage: `--name <mapping-name>`

  The name of the mapping.

* `description`
  * Type: STRING
  * Default: ``
  * Usage: `--description <mapping-description>`

  The description of the mapping.

* `file`
  * Type: STRING
  * Default: ``
  * Usage: `--file <mapping-file>`

  The mapping file. Must be a CSV file.

* `matchers`
  * Type: STRING
  * Default: ``
  * Usage: `--matchers <mapping-matchers>`

  The matchers of the mapping, as a comma-separated list of strings.

* `priority`
  * Type: INTEGER RANGE
  * Default: `0`
  * Usage: `--priority <priority>`

  The priority of the mapping, higher priority means this rule will execute first. `0<=x<=100`.

* `help`:
  * Type: BOOL
  * Default: `false`
  * Usage: `--help`

  Show this message and exit.

## CLI Help

```
Usage: keep mappings create [OPTIONS]

  Create a mapping rule.

Options:
  -n, --name TEXT               The name of the mapping.  [required]
  -d, --description TEXT        The description of the mapping.
  -f, --file PATH               The mapping file. Must be a CSV file.
                                [required]
  -m, --matchers TEXT           The matchers of the mapping, as a comma-
                                separated list of strings.  [required]
  -p, --priority INTEGER RANGE  The priority of the mapping, higher priority
                                means this rule will execute first.
                                [0<=x<=100]
  --help                        Show this message and exit.
```


================================================
FILE: docs/cli/commands/mappings-delete.mdx
================================================
---
sidebarTitle: "keep mappings delete"
---

Delete a mapping with a specified ID.

## Usage

```
Usage: keep mappings delete [OPTIONS]
```

## Options

* `mapping-id`
  * Type: STRING
  * Default: ``
  * Usage: `--mapping-id <mapping-id>`

  The ID of the mapping to delete.

* `help`:
  * Type: BOOL
  * Default: `false`
  * Usage: `--help`

  Show this message and exit.



## CLI Help

```
Usage: keep mappings delete [OPTIONS]

  Delete a mapping with a specified ID

Options:
  --mapping-id INTEGER  The ID of the mapping to delete.  [required]
  --help                Show this message and exit.
```


================================================
FILE: docs/cli/commands/mappings-list.mdx
================================================
---
sidebarTitle: "keep mappings list"
---

List mappings.

## Usage

```
Usage: keep mappings [OPTIONS]
```

List mappings.

## Options

* `help`:
  * Type: BOOL
  * Default: `false`
  * Usage: `--help`

  Show this message and exit.

## CLI Help

```
Usage: keep mappings list [OPTIONS]

  List mappings.

Options:
  --help  Show this message and exit.
```


================================================
FILE: docs/cli/commands/provider-connect.mdx
================================================
---
sidebarTitle: "keep provider connect"
---

Connect a provider.

## Usage

```
Usage: keep provider connect [OPTIONS] PROVIDER_TYPE [PARAMS]...
```

## Options


## CLI Help

```
Usage: keep provider connect [OPTIONS] PROVIDER_TYPE [PARAMS]...

Options:
  -h, --help                Help on how to install this provider.
  -n, --provider-name TEXT  Every provider shuold have a name.
```


================================================
FILE: docs/cli/commands/provider-delete.mdx
================================================
---
sidebarTitle: "keep provider delete"
---

Delete a provider.

## Usage

```
Usage: keep provider delete [OPTIONS] [PROVIDER_ID]
```

## Options


## CLI Help

```
Usage: keep provider delete [OPTIONS] [PROVIDER_ID]

Options:
  --help  Show this message and exit.
```


================================================
FILE: docs/cli/commands/provider-list.mdx
================================================
---
sidebarTitle: "keep provider list"
---

List providers.

## Usage

```
Usage: keep provider list [OPTIONS]
```

## Options
* `available`:
  * Type: BOOL
  * Default: `false`
  * Usage: `--available
-a`

  List provider that you can install.


* `help`:
  * Type: BOOL
  * Default: `false`
  * Usage: `--help`

  Show this message and exit.



## CLI Help

```
Usage: keep provider list [OPTIONS]

  List providers.

Options:
  -a, --available  List provider that you can install.
  --help           Show this message and exit.
```


================================================
FILE: docs/cli/commands/runs-list.mdx
================================================
---
sidebarTitle: "keep workflow runs list"
---

List workflow executions.

## Usage

```
Usage: keep workflow runs list [OPTIONS]
```

## Options
* `help`:
  * Type: BOOL
  * Default: `false`
  * Usage: `--help`

  Show this message and exit.



## CLI Help

```
Usage: keep workflow runs list [OPTIONS]

  List workflow executions.

Options:
  --help  Show this message and exit.
```


================================================
FILE: docs/cli/commands/runs-logs.mdx
================================================
---
sidebarTitle: "keep workflow runs logs"
---

Get workflow execution logs.

## Usage

```
Usage: keep workflow runs logs [OPTIONS] WORKFLOW_EXECUTION_ID
```

## Options


## CLI Help

```
Usage: keep workflow runs logs [OPTIONS] WORKFLOW_EXECUTION_ID

  Get workflow execution logs.

Options:
  --help  Show this message and exit.
```


================================================
FILE: docs/cli/commands/workflow-apply.mdx
================================================
---
sidebarTitle: "keep workflow apply"
---


Apply a workflow.

## Usage

```
Usage: keep workflow apply [OPTIONS]
```

## Options
* `file` (REQUIRED):
  * Type: Path
  * Default: `none`
  * Usage: `--file
-f`

  The workflow file


* `help`:
  * Type: BOOL
  * Default: `false`
  * Usage: `--help`

  Show this message and exit.



## CLI Help

```
Usage: keep workflow apply [OPTIONS]

  Apply a workflow.

Options:
  -f, --file PATH  The workflow file  [required]
  --help           Show this message and exit.
```


================================================
FILE: docs/cli/commands/workflow-list.mdx
================================================
---
sidebarTitle: "keep workflow list"
---

List workflows.

## Usage

```
Usage: keep workflow list [OPTIONS]
```

## Options
* `help`:
  * Type: BOOL
  * Default: `false`
  * Usage: `--help`

  Show this message and exit.



## CLI Help

```
Usage: keep workflow list [OPTIONS]

  List workflows.

Options:
  --help  Show this message and exit.
```


================================================
FILE: docs/cli/commands/workflow-run.mdx
================================================
---
sidebarTitle: "keep workflow run"
---

Run a workflow with a specified ID and fingerprint.

## Usage

```
Usage: keep workflow run [OPTIONS]
```

## Options
* `workflow_id` (REQUIRED):
  * Type: STRING
  * Default: `none`
  * Usage: `--workflow-id`

  The ID (UUID or name) of the workflow to run


* `fingerprint` (REQUIRED):
  * Type: STRING
  * Default: `none`
  * Usage: `--fingerprint`

  The fingerprint to query the payload


* `help`:
  * Type: BOOL
  * Default: `false`
  * Usage: `--help`

  Show this message and exit.



## CLI Help

```
Usage: keep workflow run [OPTIONS]

  Run a workflow with a specified ID and fingerprint.

Options:
  --workflow-id TEXT  The ID (UUID or name) of the workflow to run  [required]
  --fingerprint TEXT  The fingerprint to query the payload  [required]
  --help              Show this message and exit.
```


================================================
FILE: docs/cli/commands/workflow-runs.mdx
================================================
---
sidebarTitle: "keep workflow runs"
---

Manage workflows executions.

## Usage

```
Usage: cli workflow runs [OPTIONS] COMMAND [ARGS]...
```

## Options
* `help`:
  * Type: BOOL
  * Default: `false`
  * Usage: `--help`

  Show this message and exit.



## CLI Help

```
Usage: cli workflow runs [OPTIONS] COMMAND [ARGS]...

  Manage workflows executions.

Options:
  --help  Show this message and exit.

Commands:
  list  List workflow executions.
  logs  Get workflow execution logs.
```


================================================
FILE: docs/cli/github-actions.mdx
================================================
---
title: "Sync Keep Workflows With Github Action"
---

This documentation provides a detailed guide on how to use the Keep CLI within a GitHub Actions workflow to synchronize and manage Keep workflows from a directory. This setup automates the process of uploading workflows to Keep, making it easier to maintain and update them.





### Configuration
To set up this workflow in your repository:

- Add the workflow YAML file to your repository under `.github/workflows/`.
- Set your Keep API Key and URL as secrets in your repository settings if you haven't already.
- Make changes to your workflows in the specified directory or trigger the workflow manually through the GitHub UI.
- Change 'example/workflows/**' to the directory you store your Keep Workflows.


### GitHub Action Workflow
This GitHub Actions workflow automatically synchronizes workflows from a specified directory to Keep whenever there are changes. It also allows for manual triggering with optional parameters.

```yaml
# A workflow that sync Keep workflows from a directory
name: "Sync Keep Workflows"

on:
    push:
        paths:
          - 'examples/workflows/**'
    workflow_dispatch:
        inputs:
            keep_api_key:
              description: 'Keep API Key'
              required: false
            keep_api_url:
              description: 'Keep API URL'
              required: false
              default: 'https://api.keephq.dev'

jobs:
    sync-workflows:
        name: Sync workflows to Keep
        runs-on: ubuntu-latest
        container:
            image: us-central1-docker.pkg.dev/keephq/keep/keep-cli:latest
        env:
            KEEP_API_KEY: ${{ secrets.KEEP_API_KEY || github.event.inputs.keep_api_key }}
            KEEP_API_URL: ${{ secrets.KEEP_API_URL || github.event.inputs.keep_api_url }}

        steps:
        - name: Check out the repo
          uses: actions/checkout@v2

        - name: Run Keep CLI
          run: |
            keep workflow apply -f examples/workflows

```


================================================
FILE: docs/cli/installation.mdx
================================================
---
title: "Installation"
---
<Info>Missing an installation? submit a <a href="https://github.com/keephq/keep/issues/new?assignees=&labels=&projects=&template=use_case.md&title=">new installation</a>  request and we will add it as soon as we can.</Info>

<Info>
We recommend to install Keep CLI with Python version 3.11 for optimal compatibility and performance.
This choice ensures seamless integration with all dependencies, including pyarrow, which currently does not support Python 3.12
</Info>

<Tip>Need Keep CLI on other versions? Feel free to contact us! </Tip>

## Clone and install (Option 1)

### Install
First, clone Keep repository:

```shell
git clone https://github.com/keephq/keep.git && cd keep
```

Install Keep CLI with `pip`:

```shell
# MacOS if python or pip not present:
# brew install python@3.11
# brew install postgresql
pip3.11 install .
```
or with `poetry`:

```shell
poetry install
```

From now on, Keep should be installed locally and accessible from your CLI, test it by executing:

```
keep version
```

### Configuration

To get API key, check Keep UI -> your username (bottom left) -> Settings -> API Keys
```
keep config new --url http://backend.my_keep.my_awesome_org.com:backend_port --api-key your_personal_api_key
```

### Test

Now, 
```
keep workflow apply -f examples/workflows/query_clickhouse.yml
```

Congrats 🥳 Check your UI for the new workflow uploaded from the YAML file.


## Docker image (Option 2)
### Install

```
docker run -v ${PWD}:/app -v ~/.keep.yaml:/root/.keep.yaml -it us-central1-docker.pkg.dev/keephq/keep/keep-cli keep config new --url http://backend.my_keep.my_awesome_org.com:backend_port --api-key your_personal_api_key
```

### Test
```
docker run -v ${PWD}:/app -v ~/.keep.yaml:/root/.keep.yaml -it us-central1-docker.pkg.dev/keephq/keep/keep-cli workflow apply -f examples/workflows/query_clickhouse.yml
```


## Enable Auto Completion
Keep's CLI supports shell auto-completion, which can make your life a whole lot easier 😌
If you're using zsh

```shell title=~/.zshrc
eval "$(_KEEP_COMPLETE=zsh_source keep)"
```

If you're using bash

```bash title=~/.bashrc
eval "$(_KEEP_COMPLETE=bash_source keep)"
```

<Info>Using eval means that the command is invoked and evaluated every time a shell is started, which can delay shell responsiveness. To speed it up, write the generated script to a file, then source that.</Info>


================================================
FILE: docs/cli/overview.mdx
================================================
---
title: "Overview"
---

Keep CLI allow you to manage Keep from CLI.

Start by [installing](/cli/installation) Keep CLI and [running a workflow]
Download .txt
gitextract_gaok0hlb/

├── .cursor/
│   └── rules/
│       ├── keep-ui-react-typescript.mdc
│       └── keep-ui-tests.mdc
├── .dockerignore
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── config.yml
│   │   ├── documentation.md
│   │   ├── feature_request.md
│   │   ├── new_provider_request.md
│   │   └── use_case.md
│   └── workflows/
│       ├── auto-release.yml
│       ├── auto-resolve-keep.yml
│       ├── but-to-project.yml
│       ├── developer-onboarding-notification.yml
│       ├── lint-pr.yml
│       ├── release-workflow-schema.yml
│       ├── release.yml
│       ├── run-e2e-tests.yml
│       ├── sync-keep-workflows.yml
│       ├── test-docs.yml
│       ├── test-pr-e2e.yml
│       ├── test-pr-integrations.yml
│       ├── test-pr-ut-ui.yml
│       ├── test-pr-ut.yml
│       └── test-workflow-examples.yml
├── .gitignore
├── .pre-commit-config.yaml
├── .python-version
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── docker/
│   ├── Dockerfile.api
│   ├── Dockerfile.cli
│   ├── Dockerfile.dev.api
│   ├── Dockerfile.dev.ui
│   └── Dockerfile.ui
├── docker-compose-with-arq.yml
├── docker-compose-with-auth.yml
├── docker-compose-with-otel.yaml
├── docker-compose.common.yml
├── docker-compose.dev.yml
├── docker-compose.yml
├── docs/
│   ├── README.md
│   ├── alertevaluation/
│   │   ├── examples/
│   │   │   ├── victoriametricsmulti.mdx
│   │   │   └── victoriametricssingle.mdx
│   │   └── overview.mdx
│   ├── alerts/
│   │   ├── actionmenu.mdx
│   │   ├── overview.mdx
│   │   ├── presets.mdx
│   │   ├── sidebar.mdx
│   │   ├── sound.mdx
│   │   └── table.mdx
│   ├── applications/
│   │   └── github.mdx
│   ├── authentication/
│   │   └── okta.md
│   ├── cli/
│   │   ├── commands/
│   │   │   ├── alert-enrich.mdx
│   │   │   ├── alert-get.mdx
│   │   │   ├── alert-list.mdx
│   │   │   ├── cli-alert.mdx
│   │   │   ├── cli-api.mdx
│   │   │   ├── cli-config-new.mdx
│   │   │   ├── cli-config-show.mdx
│   │   │   ├── cli-config.mdx
│   │   │   ├── cli-provider.mdx
│   │   │   ├── cli-run.mdx
│   │   │   ├── cli-version.mdx
│   │   │   ├── cli-whoami.mdx
│   │   │   ├── cli-workflow.mdx
│   │   │   ├── cli.mdx
│   │   │   ├── extraction-create.mdx
│   │   │   ├── extraction-delete.mdx
│   │   │   ├── extractions-list.mdx
│   │   │   ├── mappings-create.mdx
│   │   │   ├── mappings-delete.mdx
│   │   │   ├── mappings-list.mdx
│   │   │   ├── provider-connect.mdx
│   │   │   ├── provider-delete.mdx
│   │   │   ├── provider-list.mdx
│   │   │   ├── runs-list.mdx
│   │   │   ├── runs-logs.mdx
│   │   │   ├── workflow-apply.mdx
│   │   │   ├── workflow-list.mdx
│   │   │   ├── workflow-run.mdx
│   │   │   └── workflow-runs.mdx
│   │   ├── github-actions.mdx
│   │   ├── installation.mdx
│   │   └── overview.mdx
│   ├── deployment/
│   │   ├── authentication/
│   │   │   ├── auth0-auth.mdx
│   │   │   ├── azuread-auth.mdx
│   │   │   ├── db-auth.mdx
│   │   │   ├── keycloak-auth.mdx
│   │   │   ├── no-auth.mdx
│   │   │   ├── oauth2-proxy-gitlab.mdx
│   │   │   ├── oauth2proxy-auth.mdx
│   │   │   ├── okta-auth.mdx
│   │   │   ├── onelogin-auth.mdx
│   │   │   └── overview.mdx
│   │   ├── configuration.mdx
│   │   ├── docker.mdx
│   │   ├── ecs.mdx
│   │   ├── kubernetes/
│   │   │   ├── architecture.mdx
│   │   │   ├── installation.mdx
│   │   │   ├── openshift.mdx
│   │   │   └── overview.mdx
│   │   ├── local-llm/
│   │   │   └── keep-with-litellm.mdx
│   │   ├── monitoring.mdx
│   │   ├── provision/
│   │   │   ├── dashboard.mdx
│   │   │   ├── overview.mdx
│   │   │   ├── provider.mdx
│   │   │   └── workflow.mdx
│   │   ├── secret-store.mdx
│   │   └── stress-testing.mdx
│   ├── development/
│   │   ├── external-url.mdx
│   │   └── getting-started.mdx
│   ├── images/
│   │   └── datadog_raw_alerts.txt
│   ├── incidents/
│   │   ├── facets.mdx
│   │   └── overview.mdx
│   ├── mint.json
│   ├── openapi.json
│   ├── overview/
│   │   ├── ai-correlation.mdx
│   │   ├── ai-in-workflows.mdx
│   │   ├── ai-incident-assistant.mdx
│   │   ├── ai-semi-automatic-correlation.mdx
│   │   ├── ai-workflow-assistant.mdx
│   │   ├── alertseverityandstatus.mdx
│   │   ├── cel.mdx
│   │   ├── comparisons.mdx
│   │   ├── correlation-rules.mdx
│   │   ├── correlation-topology.mdx
│   │   ├── deduplication.mdx
│   │   ├── enrichment/
│   │   │   ├── extraction.mdx
│   │   │   └── mapping.mdx
│   │   ├── faq.mdx
│   │   ├── fingerprints.mdx
│   │   ├── glossary.mdx
│   │   ├── howdoeskeepgetmyalerts.mdx
│   │   ├── introduction.mdx
│   │   ├── maintenance-windows.mdx
│   │   ├── playground.mdx
│   │   ├── servicetopology.mdx
│   │   ├── support.mdx
│   │   ├── usecases.mdx
│   │   └── workflow-automation.mdx
│   ├── providers/
│   │   ├── adding-a-new-provider.mdx
│   │   ├── documentation/
│   │   │   ├── airflow-provider.mdx
│   │   │   ├── aks-provider.mdx
│   │   │   ├── amazonsqs-provider.mdx
│   │   │   ├── anthropic-provider.mdx
│   │   │   ├── appdynamics-provider.mdx
│   │   │   ├── argocd-provider.mdx
│   │   │   ├── asana-provider.mdx
│   │   │   ├── auth0-provider.mdx
│   │   │   ├── axiom-provider.mdx
│   │   │   ├── azuremonitoring-provider.mdx
│   │   │   ├── bash-provider.mdx
│   │   │   ├── bigquery-provider.mdx
│   │   │   ├── centreon-provider.mdx
│   │   │   ├── checkly-provider.mdx
│   │   │   ├── checkmk-provider.mdx
│   │   │   ├── cilium-provider.mdx
│   │   │   ├── clickhouse-provider.mdx
│   │   │   ├── cloudwatch-provider.mdx
│   │   │   ├── console-provider.mdx
│   │   │   ├── coralogix-provider.mdx
│   │   │   ├── dash0-provider.mdx
│   │   │   ├── databend-provider.mdx
│   │   │   ├── datadog-provider.mdx
│   │   │   ├── deepseek-provider.mdx
│   │   │   ├── discord-provider.mdx
│   │   │   ├── dynatrace-provider.mdx
│   │   │   ├── eks-provider.mdx
│   │   │   ├── elastic-provider.mdx
│   │   │   ├── flashduty-provider.mdx
│   │   │   ├── fluxcd-provider.mdx
│   │   │   ├── gcpmonitoring-provider.mdx
│   │   │   ├── gemini-provider.mdx
│   │   │   ├── github-provider.mdx
│   │   │   ├── github_workflows_provider.mdx
│   │   │   ├── gitlab-provider.mdx
│   │   │   ├── gitlabpipelines-provider.mdx
│   │   │   ├── gke-provider.mdx
│   │   │   ├── google_chat-provider.mdx
│   │   │   ├── grafana-provider.mdx
│   │   │   ├── grafana_incident-provider.mdx
│   │   │   ├── grafana_loki-provider.mdx
│   │   │   ├── grafana_oncall-provider.mdx
│   │   │   ├── graylog-provider.mdx
│   │   │   ├── grok-provider.mdx
│   │   │   ├── http-provider.mdx
│   │   │   ├── icinga2-provider.mdx
│   │   │   ├── ilert-provider.mdx
│   │   │   ├── incidentio-provider.mdx
│   │   │   ├── incidentmanager-provider.mdx
│   │   │   ├── jira-on-prem-provider.mdx
│   │   │   ├── jira-provider.mdx
│   │   │   ├── kafka-provider.mdx
│   │   │   ├── keep-provider.mdx
│   │   │   ├── kibana-provider.mdx
│   │   │   ├── kubernetes-provider.mdx
│   │   │   ├── libre_nms-provider.mdx
│   │   │   ├── linear_provider.mdx
│   │   │   ├── linearb-provider.mdx
│   │   │   ├── litellm-provider.mdx
│   │   │   ├── llamacpp-provider.mdx
│   │   │   ├── mailgun-provider.mdx
│   │   │   ├── mattermost-provider.mdx
│   │   │   ├── mock-provider.mdx
│   │   │   ├── monday-provider.mdx
│   │   │   ├── mongodb-provider.mdx
│   │   │   ├── mysql-provider.mdx
│   │   │   ├── netbox-provider.mdx
│   │   │   ├── netdata-provider.mdx
│   │   │   ├── new-relic-provider.mdx
│   │   │   ├── ntfy-provider.mdx
│   │   │   ├── ollama-provider.mdx
│   │   │   ├── openai-provider.mdx
│   │   │   ├── openobserve-provider.mdx
│   │   │   ├── opensearchserverless-provider.mdx
│   │   │   ├── openshift-provider.mdx
│   │   │   ├── opsgenie-provider.mdx
│   │   │   ├── pagerduty-provider.mdx
│   │   │   ├── pagertree-provider.mdx
│   │   │   ├── parseable-provider.mdx
│   │   │   ├── pingdom-provider.mdx
│   │   │   ├── planner-provider.mdx
│   │   │   ├── postgresql-provider.mdx
│   │   │   ├── posthog-provider.mdx
│   │   │   ├── prometheus-provider.mdx
│   │   │   ├── pushover-provider.mdx
│   │   │   ├── python-provider.mdx
│   │   │   ├── quickchart-provider.mdx
│   │   │   ├── redmine-provider.mdx
│   │   │   ├── resend-provider.mdx
│   │   │   ├── rollbar-provider.mdx
│   │   │   ├── s3-provider.mdx
│   │   │   ├── sendgrid-provider.mdx
│   │   │   ├── sentry-provider.mdx
│   │   │   ├── service-now-provider.mdx
│   │   │   ├── signalfx-provider.mdx
│   │   │   ├── signl4-provider.mdx
│   │   │   ├── site24x7-provider.mdx
│   │   │   ├── slack-provider.mdx
│   │   │   ├── smtp-provider.mdx
│   │   │   ├── snowflake-provider.mdx
│   │   │   ├── splunk-provider.mdx
│   │   │   ├── squadcast-provider.mdx
│   │   │   ├── ssh-provider.mdx
│   │   │   ├── statuscake-provider.mdx
│   │   │   ├── sumologic-provider.mdx
│   │   │   ├── teams-provider.mdx
│   │   │   ├── telegram-provider.mdx
│   │   │   ├── template.mdx
│   │   │   ├── thousandeyes-provider.mdx
│   │   │   ├── trello-provider.mdx
│   │   │   ├── twilio-provider.mdx
│   │   │   ├── uptimekuma-provider.mdx
│   │   │   ├── victorialogs-provider.mdx
│   │   │   ├── victoriametrics-provider.mdx
│   │   │   ├── vllm-provider.mdx
│   │   │   ├── wazuh-provider.mdx
│   │   │   ├── webhook-provider.mdx
│   │   │   ├── websocket-provider.mdx
│   │   │   ├── youtrack-provider.mdx
│   │   │   ├── zabbix-provider.mdx
│   │   │   ├── zenduty-provider.mdx
│   │   │   ├── zoom-provider.mdx
│   │   │   └── zoom_chat-provider.mdx
│   │   ├── linked-providers.mdx
│   │   ├── overview.md
│   │   ├── overview.mdx
│   │   └── provider-methods.mdx
│   ├── snippets/
│   │   └── providers/
│   │       ├── airflow-snippet-autogenerated.mdx
│   │       ├── aks-snippet-autogenerated.mdx
│   │       ├── amazonsqs-snippet-autogenerated.mdx
│   │       ├── anthropic-snippet-autogenerated.mdx
│   │       ├── appdynamics-snippet-autogenerated.mdx
│   │       ├── argocd-snippet-autogenerated.mdx
│   │       ├── asana-snippet-autogenerated.mdx
│   │       ├── auth0-snippet-autogenerated.mdx
│   │       ├── axiom-snippet-autogenerated.mdx
│   │       ├── azuremonitoring-snippet-autogenerated.mdx
│   │       ├── base-snippet-autogenerated.mdx
│   │       ├── bash-snippet-autogenerated.mdx
│   │       ├── bigquery-snippet-autogenerated.mdx
│   │       ├── centreon-snippet-autogenerated.mdx
│   │       ├── checkly-snippet-autogenerated.mdx
│   │       ├── checkmk-snippet-autogenerated.mdx
│   │       ├── cilium-snippet-autogenerated.mdx
│   │       ├── clickhouse-snippet-autogenerated.mdx
│   │       ├── cloudwatch-snippet-autogenerated.mdx
│   │       ├── console-snippet-autogenerated.mdx
│   │       ├── coralogix-snippet-autogenerated.mdx
│   │       ├── dash0-snippet-autogenerated.mdx
│   │       ├── databend-snippet-autogenerated.mdx
│   │       ├── datadog-snippet-autogenerated.mdx
│   │       ├── deepseek-snippet-autogenerated.mdx
│   │       ├── discord-snippet-autogenerated.mdx
│   │       ├── dynatrace-snippet-autogenerated.mdx
│   │       ├── eks-snippet-autogenerated.mdx
│   │       ├── elastic-snippet-autogenerated.mdx
│   │       ├── flashduty-snippet-autogenerated.mdx
│   │       ├── fluxcd-snippet-autogenerated.mdx
│   │       ├── gcpmonitoring-snippet-autogenerated.mdx
│   │       ├── gemini-snippet-autogenerated.mdx
│   │       ├── github-snippet-autogenerated.mdx
│   │       ├── github_workflows-snippet-autogenerated.mdx
│   │       ├── gitlab-snippet-autogenerated.mdx
│   │       ├── gitlabpipelines-snippet-autogenerated.mdx
│   │       ├── gke-snippet-autogenerated.mdx
│   │       ├── google_chat-snippet-autogenerated.mdx
│   │       ├── grafana-snippet-autogenerated.mdx
│   │       ├── grafana_incident-snippet-autogenerated.mdx
│   │       ├── grafana_loki-snippet-autogenerated.mdx
│   │       ├── grafana_oncall-snippet-autogenerated.mdx
│   │       ├── graylog-snippet-autogenerated.mdx
│   │       ├── grok-snippet-autogenerated.mdx
│   │       ├── http-snippet-autogenerated.mdx
│   │       ├── icinga2-snippet-autogenerated.mdx
│   │       ├── ilert-snippet-autogenerated.mdx
│   │       ├── incidentio-snippet-autogenerated.mdx
│   │       ├── incidentmanager-snippet-autogenerated.mdx
│   │       ├── jira-snippet-autogenerated.mdx
│   │       ├── jiraonprem-snippet-autogenerated.mdx
│   │       ├── kafka-snippet-autogenerated.mdx
│   │       ├── keep-snippet-autogenerated.mdx
│   │       ├── kibana-snippet-autogenerated.mdx
│   │       ├── kubernetes-snippet-autogenerated.mdx
│   │       ├── libre_nms-snippet-autogenerated.mdx
│   │       ├── linear-snippet-autogenerated.mdx
│   │       ├── linearb-snippet-autogenerated.mdx
│   │       ├── litellm-snippet-autogenerated.mdx
│   │       ├── llamacpp-snippet-autogenerated.mdx
│   │       ├── mailgun-snippet-autogenerated.mdx
│   │       ├── mattermost-snippet-autogenerated.mdx
│   │       ├── mock-snippet-autogenerated.mdx
│   │       ├── monday-snippet-autogenerated.mdx
│   │       ├── mongodb-snippet-autogenerated.mdx
│   │       ├── mysql-snippet-autogenerated.mdx
│   │       ├── netbox-snippet-autogenerated.mdx
│   │       ├── netdata-snippet-autogenerated.mdx
│   │       ├── netxms-snippet-autogenerated.mdx
│   │       ├── newrelic-snippet-autogenerated.mdx
│   │       ├── ntfy-snippet-autogenerated.mdx
│   │       ├── ollama-snippet-autogenerated.mdx
│   │       ├── openai-snippet-autogenerated.mdx
│   │       ├── openobserve-snippet-autogenerated.mdx
│   │       ├── opensearchserverless-snippet-autogenerated.mdx
│   │       ├── openshift-snippet-autogenerated.mdx
│   │       ├── opsgenie-snippet-autogenerated.mdx
│   │       ├── pagerduty-snippet-autogenerated.mdx
│   │       ├── pagertree-snippet-autogenerated.mdx
│   │       ├── parseable-snippet-autogenerated.mdx
│   │       ├── pingdom-snippet-autogenerated.mdx
│   │       ├── planner-snippet-autogenerated.mdx
│   │       ├── postgres-snippet-autogenerated.mdx
│   │       ├── posthog-snippet-autogenerated.mdx
│   │       ├── prometheus-snippet-autogenerated.mdx
│   │       ├── pushover-snippet-autogenerated.mdx
│   │       ├── python-snippet-autogenerated.mdx
│   │       ├── quickchart-snippet-autogenerated.mdx
│   │       ├── redmine-snippet-autogenerated.mdx
│   │       ├── resend-snippet-autogenerated.mdx
│   │       ├── rollbar-snippet-autogenerated.mdx
│   │       ├── s3-snippet-autogenerated.mdx
│   │       ├── salesforce-snippet-autogenerated.mdx
│   │       ├── sendgrid-snippet-autogenerated.mdx
│   │       ├── sentry-snippet-autogenerated.mdx
│   │       ├── servicenow-snippet-autogenerated.mdx
│   │       ├── signalfx-snippet-autogenerated.mdx
│   │       ├── signl4-snippet-autogenerated.mdx
│   │       ├── site24x7-snippet-autogenerated.mdx
│   │       ├── slack-snippet-autogenerated.mdx
│   │       ├── smtp-snippet-autogenerated.mdx
│   │       ├── snowflake-snippet-autogenerated.mdx
│   │       ├── splunk-snippet-autogenerated.mdx
│   │       ├── squadcast-snippet-autogenerated.mdx
│   │       ├── ssh-snippet-autogenerated.mdx
│   │       ├── statuscake-snippet-autogenerated.mdx
│   │       ├── sumologic-snippet-autogenerated.mdx
│   │       ├── teams-snippet-autogenerated.mdx
│   │       ├── telegram-snippet-autogenerated.mdx
│   │       ├── test_fluxcd-snippet-autogenerated.mdx
│   │       ├── thousandeyes-snippet-autogenerated.mdx
│   │       ├── trello-snippet-autogenerated.mdx
│   │       ├── twilio-snippet-autogenerated.mdx
│   │       ├── uptimekuma-snippet-autogenerated.mdx
│   │       ├── vectordev-snippet-autogenerated.mdx
│   │       ├── victorialogs-snippet-autogenerated.mdx
│   │       ├── victoriametrics-snippet-autogenerated.mdx
│   │       ├── vllm-snippet-autogenerated.mdx
│   │       ├── wazuh-snippet-autogenerated.mdx
│   │       ├── webhook-snippet-autogenerated.mdx
│   │       ├── websocket-snippet-autogenerated.mdx
│   │       ├── youtrack-snippet-autogenerated.mdx
│   │       ├── zabbix-snippet-autogenerated.mdx
│   │       ├── zendesk-snippet-autogenerated.mdx
│   │       ├── zenduty-snippet-autogenerated.mdx
│   │       ├── zoom-snippet-autogenerated.mdx
│   │       └── zoom_chat-snippet-autogenerated.mdx
│   └── workflows/
│       ├── examples/
│       │   ├── autosupress.mdx
│       │   ├── buisnesshours.mdx
│       │   ├── create-servicenow-tickets.mdx
│       │   ├── highsev.mdx
│       │   └── update-servicenow-tickets.mdx
│       ├── overview.mdx
│       └── syntax/
│           ├── conditions.mdx
│           ├── context.mdx
│           ├── enrichment.mdx
│           ├── foreach.mdx
│           ├── functions.mdx
│           ├── permissions.mdx
│           ├── providers.mdx
│           ├── steps-and-actions.mdx
│           └── triggers.mdx
├── ee/
│   ├── LICENSE
│   └── identitymanager/
│       ├── __init__.py
│       └── identity_managers/
│           ├── __init__.py
│           ├── auth0/
│           │   ├── __init__.py
│           │   ├── auth0_authverifier.py
│           │   ├── auth0_identitymanager.py
│           │   └── auth0_utils.py
│           ├── azuread/
│           │   ├── __init__.py
│           │   ├── azuread_authverifier.py
│           │   └── azuread_identitymanager.py
│           └── keycloak/
│               ├── __init__.py
│               ├── keycloak_authverifier.py
│               └── keycloak_identitymanager.py
├── elk/
│   ├── README.md
│   ├── docker-compose-elk.yml
│   ├── filebeat.yml
│   └── logstash.conf
├── examples/
│   ├── providers/
│   │   ├── airflow-prod.yaml
│   │   └── telegram-bot.yaml
│   └── workflows/
│       ├── aks_basic.yml
│       ├── autosupress.yml
│       ├── bash_example.yml
│       ├── bigquery.yml
│       ├── blogpost.yml
│       ├── businesshours.yml
│       ├── change.yml
│       ├── clickhouse_multiquery.yml
│       ├── complex-conditions-cel.yml
│       ├── conditionally_run_if_ai_says_so.yaml
│       ├── console_example.yml
│       ├── consts_and_dict.yml
│       ├── consts_and_vars.yml
│       ├── create-issue-youtrack.yaml
│       ├── create-new-incident-grafana-incident.yaml
│       ├── create-task-in-asana.yaml
│       ├── create_alert_from_vm_metric.yml
│       ├── create_alert_in_keep.yml
│       ├── create_alerts_from_elastic.yml
│       ├── create_alerts_from_mysql.yml
│       ├── create_jira_ticket_upon_alerts.yml
│       ├── create_multi_alert_from_vm_metric.yml
│       ├── create_service_now_ticket_upon_alerts.yml
│       ├── datadog-log-monitor.yml
│       ├── db_disk_space_monitor.yml
│       ├── discord_basic.yml
│       ├── disk_grown_defects_rule.yml
│       ├── eks_advanced.yml
│       ├── eks_basic.yml
│       ├── elastic_basic.yml
│       ├── elastic_enrich_example.yml
│       ├── enrich_using_structured_output_from_deepseek.yaml
│       ├── enrich_using_structured_output_from_openai.yaml
│       ├── enrich_using_structured_output_from_vllm_qwen.yaml
│       ├── failed-to-login-workflow.yml
│       ├── flashduty_example.yml
│       ├── fluxcd_example.yml
│       ├── gcp_logging_open_ai.yaml
│       ├── gke.yml
│       ├── http_enrich.yml
│       ├── ifelse.yml
│       ├── ilert-incident-upon-alert.yaml
│       ├── incident-enrich.yaml
│       ├── incident-tier-escalation.yml
│       ├── incident_example.yml
│       ├── inputs_example.yml
│       ├── jira-create-ticket-on-alert.yml
│       ├── jira-transition-on-resolved.yml
│       ├── jira_on_prem.yml
│       ├── monday_create_pulse.yml
│       ├── multi-condition-cel.yml
│       ├── mustache-paths-example.yml
│       ├── new-auth0-users-monitor.yml
│       ├── new_github_stars.yml
│       ├── notify-new-trello-card.yml
│       ├── ntfy_basic.yml
│       ├── opensearchserverless_basic.yml
│       ├── openshift_basic.yml
│       ├── openshift_monitoring_and_remediation.yml
│       ├── openshift_pod_restart.yml
│       ├── opsgenie-close-alert.yml
│       ├── opsgenie-create-alert-cel.yml
│       ├── opsgenie-create-alert.yml
│       ├── opsgenie_open_alerts.yml
│       ├── pagerduty.yml
│       ├── pattern-matching-cel.yml
│       ├── permissions_example.yml
│       ├── planner_basic.yml
│       ├── posthog_example.yml
│       ├── query-databend.yml
│       ├── query_clickhouse.yml
│       ├── query_grafana_loki.yaml
│       ├── query_mongodb.yaml
│       ├── query_victorialogs.yaml
│       ├── query_victoriametrics.yml
│       ├── raw_sql_query_datetime.yml
│       ├── resolve_old_alerts.yml
│       ├── retrieve_cloudwatch_logs.yaml
│       ├── run-github-workflow.yaml
│       ├── send-message-telegram-with-htmlmd.yaml
│       ├── send_slack_message_on_failure.yaml
│       ├── send_smtp_email.yml
│       ├── send_smtp_html_email.yml
│       ├── sendgrid_basic.yml
│       ├── service-error-rate-monitor-datadog.yml
│       ├── severity_changed.yml
│       ├── signl4-alerting-workflow.yaml
│       ├── simple_http_request_ntfy.yml
│       ├── slack-message-reaction.yml
│       ├── slack-workflow-trigger.yml
│       ├── slack_basic.yml
│       ├── slack_basic_cel.yml
│       ├── slack_basic_interval.yml
│       ├── slack_message_update.yml
│       ├── squadcast_example.yml
│       ├── teams-adaptive-card-notifier.yaml
│       ├── teams-adaptive-cards-with-mentions.yaml
│       ├── telegram_advanced.yml
│       ├── telegram_basic.yml
│       ├── test_jira_create_with_custom_fields.yml
│       ├── test_jira_custom_fields_fix.yml
│       ├── update-incident-grafana-incident.yaml
│       ├── update-task-in-asana.yaml
│       ├── update_jira_ticket.yml
│       ├── update_service_now_tickets_status.yml
│       ├── update_workflows_from_http.yml
│       ├── update_workflows_from_s3.yml
│       ├── webhook_example.yml
│       ├── webhook_example_foreach.yml
│       ├── workflow_only_first_time_example.yml
│       ├── workflow_start_example.yml
│       ├── zoom_chat_example.yml
│       └── zoom_example.yml
├── keep/
│   ├── actions/
│   │   ├── __init__.py
│   │   ├── actions_exception.py
│   │   └── actions_factory.py
│   ├── alembic.ini
│   ├── api/
│   │   ├── __init__.py
│   │   ├── alert_deduplicator/
│   │   │   ├── __init__.py
│   │   │   ├── alert_deduplicator.py
│   │   │   └── deduplication_rules_provisioning.py
│   │   ├── api.py
│   │   ├── arq_pool.py
│   │   ├── arq_worker.py
│   │   ├── arq_worker_debug_patch.py
│   │   ├── arq_worker_gunicorn.py
│   │   ├── bl/
│   │   │   ├── ai_suggestion_bl.py
│   │   │   ├── dismissal_expiry_bl.py
│   │   │   ├── enrichments_bl.py
│   │   │   ├── incident_reports.py
│   │   │   ├── incidents_bl.py
│   │   │   └── maintenance_windows_bl.py
│   │   ├── config.py
│   │   ├── consts.py
│   │   ├── core/
│   │   │   ├── alerts.py
│   │   │   ├── cel_to_sql/
│   │   │   │   ├── ast_nodes.py
│   │   │   │   ├── cel_ast_converter.py
│   │   │   │   ├── properties_mapper.py
│   │   │   │   ├── properties_metadata.py
│   │   │   │   └── sql_providers/
│   │   │   │       ├── base.py
│   │   │   │       ├── get_cel_to_sql_provider_for_dialect.py
│   │   │   │       ├── mysql.py
│   │   │   │       ├── postgresql.py
│   │   │   │       └── sqlite.py
│   │   │   ├── config.py
│   │   │   ├── db.py
│   │   │   ├── db_on_start.py
│   │   │   ├── db_utils.py
│   │   │   ├── demo_mode.py
│   │   │   ├── dependencies.py
│   │   │   ├── elastic.py
│   │   │   ├── facets.py
│   │   │   ├── facets_query_builder/
│   │   │   │   ├── base_facets_query_builder.py
│   │   │   │   ├── get_facets_query_builder.py
│   │   │   │   ├── mysql.py
│   │   │   │   ├── postgresql.py
│   │   │   │   ├── sqlite.py
│   │   │   │   └── utils.py
│   │   │   ├── incidents.py
│   │   │   ├── limiter.py
│   │   │   ├── metrics.py
│   │   │   ├── report_uptime.py
│   │   │   ├── tenant_configuration.py
│   │   │   ├── tracer.py
│   │   │   └── workflows.py
│   │   ├── custom_worker.py
│   │   ├── logging.py
│   │   ├── middlewares.py
│   │   ├── models/
│   │   │   ├── __init__.py
│   │   │   ├── action.py
│   │   │   ├── action_type.py
│   │   │   ├── ai_external.py
│   │   │   ├── alert.py
│   │   │   ├── alert_audit.py
│   │   │   ├── db/
│   │   │   │   ├── action.py
│   │   │   │   ├── ai_external.py
│   │   │   │   ├── ai_suggestion.py
│   │   │   │   ├── alert.py
│   │   │   │   ├── dashboard.py
│   │   │   │   ├── enrichment_event.py
│   │   │   │   ├── extraction.py
│   │   │   │   ├── facet.py
│   │   │   │   ├── helpers.py
│   │   │   │   ├── incident.py
│   │   │   │   ├── maintenance_window.py
│   │   │   │   ├── mapping.py
│   │   │   │   ├── migrations/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── env.py
│   │   │   │   │   ├── script.py.mako
│   │   │   │   │   └── versions/
│   │   │   │   │       ├── 2024-07-11-17-10_54c1252b2c8a.py
│   │   │   │   │       ├── 2024-07-15-15-10_c37ec8f6db3e.py
│   │   │   │   │       ├── 2024-07-16-12-16_37019ca3eb2e.py
│   │   │   │   │       ├── 2024-07-17-16-46_dcbd2873dcfd.py
│   │   │   │   │       ├── 2024-07-24-13-39_9ba0aeecd4d0.py
│   │   │   │   │       ├── 2024-07-25-17-13_67f1efb93c99.py
│   │   │   │   │       ├── 2024-07-28-16-24_8e5942040de6.py
│   │   │   │   │       ├── 2024-07-29-12-51_c91b348b94f2.py
│   │   │   │   │       ├── 2024-07-29-18-10_92f4f93f2140.py
│   │   │   │   │       ├── 2024-08-05-13-09_4147d9e706c0.py
│   │   │   │   │       ├── 2024-08-11-17-38_9453855f3ba0.py
│   │   │   │   │       ├── 2024-08-13-19-22_0832e0d9889a.py
│   │   │   │   │       ├── 2024-08-14-18-30_87594ea6d308.py
│   │   │   │   │       ├── 2024-08-25-16-40_4ef2c767664c.py
│   │   │   │   │       ├── 2024-08-25-16-48_1c650a429672.py
│   │   │   │   │       ├── 2024-08-30-09-34_7ed12220a0d3.py
│   │   │   │   │       ├── 2024-09-01-14-04_94886bc59c11.py
│   │   │   │   │       ├── 2024-09-02-12-07_70671c95028e.py
│   │   │   │   │       ├── 2024-09-03-10-08_49e7c02579db.py
│   │   │   │   │       ├── 2024-09-03-16-24_1a5eb7069f9a.py
│   │   │   │   │       ├── 2024-09-04-13-09_e6653be70b62.py
│   │   │   │   │       ├── 2024-09-08-17-51_1aacee84447e.py
│   │   │   │   │       ├── 2024-09-13-10-48_938b1aa62d5c.py
│   │   │   │   │       ├── 2024-09-17-23-30_c5443d9deb0f.py
│   │   │   │   │       ├── 2024-09-18-02-05_772790c2e50a.py
│   │   │   │   │       ├── 2024-09-18-14-08_5d7ae55efc6a.py
│   │   │   │   │       ├── 2024-09-19-15-26_493f217af6b6.py
│   │   │   │   │       ├── 2024-09-22-14-16_01ebe17218c0.py
│   │   │   │   │       ├── 2024-10-05-18-37_017d759805d9.py
│   │   │   │   │       ├── 2024-10-08-10-47_bf756df80e9d.py
│   │   │   │   │       ├── 2024-10-14-08-34_83c1020be97d.py
│   │   │   │   │       ├── 2024-10-22-10-38_8438f041ee0e.py
│   │   │   │   │       ├── 2024-10-23-15-21_89b4d3905d26.py
│   │   │   │   │       ├── 2024-10-26-17-03_3f056d747d9e.py
│   │   │   │   │       ├── 2024-10-29-18-37_991b30bcf0b9.py
│   │   │   │   │       ├── 2024-10-31-18-01_273b29f368b7.py
│   │   │   │   │       ├── 2024-11-03-10-49_ef0b5b0df41c.py
│   │   │   │   │       ├── 2024-11-08-20-58_895fe80117aa.py
│   │   │   │   │       ├── 2024-11-10-13-06_620b6c048091.py
│   │   │   │   │       ├── 2024-11-20-15-50_192157fd5788.py
│   │   │   │   │       ├── 2024-12-01-16-40_3ad5308e7200.py
│   │   │   │   │       ├── 2024-12-02-13-36_bdae8684d0b4.py
│   │   │   │   │       ├── 2024-12-02-20-42_c6e5594c99f8.py
│   │   │   │   │       ├── 2024-12-08-16-24_55cc64020f6d.py
│   │   │   │   │       ├── 2024-12-10-19-11_7297ae99cd21.py
│   │   │   │   │       ├── 2024-12-17-12-48_3d20d954e058.py
│   │   │   │   │       ├── 2024-12-23-17-22_0c5e002094a9.py
│   │   │   │   │       ├── 2024-12-23-18-49_4f8c4b185d5b.py
│   │   │   │   │       ├── 2025-01-01-09-59_dcb7f88a04da.py
│   │   │   │   │       ├── 2025-01-01-15-14_1c117f1accff.py
│   │   │   │   │       ├── 2025-01-08-19-20_8a4ec08f2d6b.py
│   │   │   │   │       ├── 2025-01-14-18-41_416155f25854.py
│   │   │   │   │       ├── 2025-01-16-14-00_e3f33e571c3c.py
│   │   │   │   │       ├── 2025-01-19-10-44_d359baaf0836.py
│   │   │   │   │       ├── 2025-01-26-15-25_8176d7153747.py
│   │   │   │   │       ├── 2025-02-05-15-46_e343054ae740.py
│   │   │   │   │       ├── 2025-02-10-12-05_908d95386e29.py
│   │   │   │   │       ├── 2025-02-11-12-59_21d314490e6a.py
│   │   │   │   │       ├── 2025-02-13-09-54_cfe08cc46950.py
│   │   │   │   │       ├── 2025-02-13-17-27_90e2d22edc6a.py
│   │   │   │   │       ├── 2025-02-18-18-09_876a424d8f06.py
│   │   │   │   │       ├── 2025-02-19-15-32_35ebba262eb0.py
│   │   │   │   │       ├── 2025-02-20-23-15_ea25d9402518.py
│   │   │   │   │       ├── 2025-02-25-14-20_a82154690f35.py
│   │   │   │   │       ├── 2025-03-05-15-55_0b80bda47ee2.py
│   │   │   │   │       ├── 2025-03-11-16-54_16309df224d1.py
│   │   │   │   │       ├── 2025-03-12-13-22_ab333148350e.py
│   │   │   │   │       ├── 2025-03-12-14-36_9f11356d8ed9.py
│   │   │   │   │       ├── 2025-03-12-14-46_ca74b4a04371.py
│   │   │   │   │       ├── 2025-03-13-14-08_c0e70149c9ec.py
│   │   │   │   │       ├── 2025-03-14-15-52_f3ecc7411f38.py
│   │   │   │   │       ├── 2025-03-16-11-08_aff0128aa8f1.py
│   │   │   │   │       ├── 2025-03-18-14-54_971abbbf0a2c.py
│   │   │   │   │       ├── 2025-03-20-09-37_c0880e315ebe.py
│   │   │   │   │       ├── 2025-03-24-14-26_2a6132b443ab.py
│   │   │   │   │       ├── 2025-03-30-10-53_e663a98b1142.py
│   │   │   │   │       ├── 2025-04-03-12-09_bdf252fbc1be.py
│   │   │   │   │       ├── 2025-04-04-21-48_0dafe96ea97f.py
│   │   │   │   │       ├── 2025-04-06-12-18_78777e6b12d3.py
│   │   │   │   │       ├── 2025-04-08-10-43_59991b568c7d.py
│   │   │   │   │       ├── 2025-04-15-15-30_885ff6b12fed.py
│   │   │   │   │       ├── 2025-04-21-10-18_819927b7ccfa.py
│   │   │   │   │       ├── 2025-05-04-15-02_eddcb77eb6f3.py
│   │   │   │   │       ├── 2025-05-06-13-09_7b687c555318.py
│   │   │   │   │       ├── 2025-05-12-17-49_c2f78c69e9cf.py
│   │   │   │   │       ├── 2025-05-15-00-34_fcef2c58b21c.py
│   │   │   │   │       ├── 2025-05-15-14-18_bedb5f07417b.py
│   │   │   │   │       ├── 2025-05-16-14-33_aa167915c4d6.py
│   │   │   │   │       ├── 2025-05-19-18-48_90e3eababbf0.py
│   │   │   │   │       ├── 2025-05-19-20-54_combined_commentmention.py
│   │   │   │   │       ├── 2025-06-04-10-43_7c14f776ef6b.py
│   │   │   │   │       └── 2025-06-18-17-17_9dd1be4539e0.py
│   │   │   │   ├── preset.py
│   │   │   │   ├── provider.py
│   │   │   │   ├── provider_image.py
│   │   │   │   ├── rule.py
│   │   │   │   ├── secret.py
│   │   │   │   ├── statistics.py
│   │   │   │   ├── system.py
│   │   │   │   ├── tenant.py
│   │   │   │   ├── topology.py
│   │   │   │   ├── user.py
│   │   │   │   └── workflow.py
│   │   │   ├── facet.py
│   │   │   ├── incident.py
│   │   │   ├── provider.py
│   │   │   ├── query.py
│   │   │   ├── search_alert.py
│   │   │   ├── severity_base.py
│   │   │   ├── smtp.py
│   │   │   ├── time_stamp.py
│   │   │   ├── user.py
│   │   │   ├── webhook.py
│   │   │   └── workflow.py
│   │   ├── observability.py
│   │   ├── redis_settings.py
│   │   ├── routes/
│   │   │   ├── __init__.py
│   │   │   ├── actions.py
│   │   │   ├── ai.py
│   │   │   ├── alerts.py
│   │   │   ├── auth/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── groups.py
│   │   │   │   ├── permissions.py
│   │   │   │   ├── roles.py
│   │   │   │   └── users.py
│   │   │   ├── cel.py
│   │   │   ├── dashboard.py
│   │   │   ├── deduplications.py
│   │   │   ├── extraction.py
│   │   │   ├── facets.py
│   │   │   ├── healthcheck.py
│   │   │   ├── incidents.py
│   │   │   ├── maintenance.py
│   │   │   ├── mapping.py
│   │   │   ├── metrics.py
│   │   │   ├── preset.py
│   │   │   ├── provider_images.py
│   │   │   ├── providers.py
│   │   │   ├── pusher.py
│   │   │   ├── rules.py
│   │   │   ├── settings.py
│   │   │   ├── status.py
│   │   │   ├── tags.py
│   │   │   ├── topology.py
│   │   │   ├── whoami.py
│   │   │   └── workflows.py
│   │   ├── tasks/
│   │   │   ├── __init__.py
│   │   │   ├── notification_cache.py
│   │   │   ├── process_event_task.py
│   │   │   ├── process_incident_task.py
│   │   │   ├── process_topology_task.py
│   │   │   └── process_watcher_task.py
│   │   └── utils/
│   │       ├── alert_utils.py
│   │       ├── cel_utils.py
│   │       ├── email_utils.py
│   │       ├── enrichment_helpers.py
│   │       ├── import_ee.py
│   │       ├── pagination.py
│   │       ├── pluralize.py
│   │       ├── tenant_utils.py
│   │       └── time_stamp_helpers.py
│   ├── cli/
│   │   ├── cli.py
│   │   └── click_extensions.py
│   ├── conditions/
│   │   ├── __init__.py
│   │   ├── assert_condition.py
│   │   ├── base_condition.py
│   │   ├── condition_factory.py
│   │   ├── stddev_condition.py
│   │   └── threshold_condition.py
│   ├── contextmanager/
│   │   ├── __init__.py
│   │   └── contextmanager.py
│   ├── entrypoint.sh
│   ├── event_subscriber/
│   │   ├── __init__.py
│   │   └── event_subscriber.py
│   ├── exceptions/
│   │   ├── __init__.py
│   │   ├── action_error.py
│   │   ├── provider_config_exception.py
│   │   ├── provider_connection_failed.py
│   │   └── provider_exception.py
│   ├── functions/
│   │   ├── __init__.py
│   │   └── cyaml.py
│   ├── identitymanager/
│   │   ├── authenticatedentity.py
│   │   ├── authverifierbase.py
│   │   ├── identity_managers/
│   │   │   ├── __init__.py
│   │   │   ├── db/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── db_authverifier.py
│   │   │   │   └── db_identitymanager.py
│   │   │   ├── noauth/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── noauth_authverifier.py
│   │   │   │   └── noauth_identitymanager.py
│   │   │   ├── oauth2proxy/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── oauth2proxy_authverifier.py
│   │   │   │   └── oauth2proxy_identitymanager.py
│   │   │   ├── okta/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── okta_authverifier.py
│   │   │   │   └── okta_identitymanager.py
│   │   │   └── onelogin/
│   │   │       ├── __init__.py
│   │   │       ├── onelogin_authverifier.py
│   │   │       └── onelogin_identitymanager.py
│   │   ├── identitymanager.py
│   │   ├── identitymanagerfactory.py
│   │   └── rbac.py
│   ├── iohandler/
│   │   └── iohandler.py
│   ├── parser/
│   │   └── parser.py
│   ├── providers/
│   │   ├── __init__.py
│   │   ├── airflow_provider/
│   │   │   ├── __init__.py
│   │   │   └── airflow_provider.py
│   │   ├── aks_provider/
│   │   │   └── aks_provider.py
│   │   ├── amazonsqs_provider/
│   │   │   ├── __init__.py
│   │   │   └── amazonsqs_provider.py
│   │   ├── anthropic_provider/
│   │   │   ├── __init__.py
│   │   │   └── anthropic_provider.py
│   │   ├── appdynamics_provider/
│   │   │   ├── __init__.py
│   │   │   ├── appdynamics_provider.py
│   │   │   └── httpactiontemplate.json
│   │   ├── argocd_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   ├── applicationset.yaml
│   │   │   └── argocd_provider.py
│   │   ├── asana_provider/
│   │   │   ├── __init__.py
│   │   │   └── asana_provider.py
│   │   ├── auth0_provider/
│   │   │   ├── __init__.py
│   │   │   └── auth0_provider.py
│   │   ├── axiom_provider/
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   └── axiom_provider.py
│   │   ├── azuremonitoring_provider/
│   │   │   ├── __init__.py
│   │   │   └── azuremonitoring_provider.py
│   │   ├── base/
│   │   │   ├── __init__.py
│   │   │   ├── base_provider.py
│   │   │   └── provider_exceptions.py
│   │   ├── bash_provider/
│   │   │   ├── __init__.py
│   │   │   └── bash_provider.py
│   │   ├── bigquery_provider/
│   │   │   ├── __init__.py
│   │   │   └── bigquery_provider.py
│   │   ├── centreon_provider/
│   │   │   ├── __init__.py
│   │   │   └── centreon_provider.py
│   │   ├── checkly_provider/
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   └── checkly_provider.py
│   │   ├── checkmk_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   ├── checkmk_provider.py
│   │   │   └── webhook-keep.py
│   │   ├── cilium_provider/
│   │   │   ├── __init__.py
│   │   │   ├── cilium_provider.py
│   │   │   ├── generate_protobuf.py
│   │   │   ├── grpc/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── flow/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── flow.proto
│   │   │   │   │   ├── flow_pb2.py
│   │   │   │   │   └── flow_pb2_grpc.py
│   │   │   │   ├── google/
│   │   │   │   │   └── protobuf/
│   │   │   │   │       ├── duration.proto
│   │   │   │   │       ├── timestamp.proto
│   │   │   │   │       └── wrappers.proto
│   │   │   │   ├── observer.proto
│   │   │   │   ├── observer_pb2.py
│   │   │   │   ├── observer_pb2_grpc.py
│   │   │   │   └── relay/
│   │   │   │       ├── __init__.py
│   │   │   │       ├── relay.proto
│   │   │   │       ├── relay_pb2.py
│   │   │   │       └── relay_pb2_grpc.py
│   │   │   └── runtime_version.py
│   │   ├── clickhouse_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   ├── clickhouse-secure/
│   │   │   │   ├── certs/
│   │   │   │   │   ├── server.crt
│   │   │   │   │   └── server.key
│   │   │   │   ├── config.xml
│   │   │   │   ├── docker-compose.yml
│   │   │   │   └── users.xml
│   │   │   └── clickhouse_provider.py
│   │   ├── cloudwatch_provider/
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   └── cloudwatch_provider.py
│   │   ├── console_provider/
│   │   │   ├── __init__.py
│   │   │   └── console_provider.py
│   │   ├── coralogix_provider/
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   └── coralogix_provider.py
│   │   ├── dash0_provider/
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   └── dash0_provider.py
│   │   ├── databend_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   └── databend_provider.py
│   │   ├── datadog_provider/
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   ├── datadog_alert_format_description.py
│   │   │   ├── datadog_provider.py
│   │   │   └── topology_mock.py
│   │   ├── deepseek_provider/
│   │   │   ├── __init__.py
│   │   │   └── deepseek_provider.py
│   │   ├── discord_provider/
│   │   │   ├── __init__.py
│   │   │   └── discord_provider.py
│   │   ├── dynatrace_provider/
│   │   │   ├── __init__.py
│   │   │   └── dynatrace_provider.py
│   │   ├── eks_provider/
│   │   │   └── eks_provider.py
│   │   ├── elastic_provider/
│   │   │   ├── __init__.py
│   │   │   └── elastic_provider.py
│   │   ├── flashduty_provider/
│   │   │   ├── __init__.py
│   │   │   └── flashduty_provider.py
│   │   ├── fluxcd_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   ├── example.yaml
│   │   │   ├── fluxcd_provider.py
│   │   │   ├── requirements.txt
│   │   │   ├── setup.py
│   │   │   └── test_fluxcd_provider.py
│   │   ├── gcpmonitoring_provider/
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   └── gcpmonitoring_provider.py
│   │   ├── gemini_provider/
│   │   │   ├── __init__.py
│   │   │   └── gemini_provider.py
│   │   ├── github_provider/
│   │   │   ├── __init__.py
│   │   │   └── github_provider.py
│   │   ├── github_workflows_provider/
│   │   │   ├── __init__.py
│   │   │   └── github_workflows_provider.py
│   │   ├── gitlab_provider/
│   │   │   ├── __init__.py
│   │   │   └── gitlab_provider.py
│   │   ├── gitlabpipelines_provider/
│   │   │   ├── __init__.py
│   │   │   └── gitlabpipelines_provider.py
│   │   ├── gke_provider/
│   │   │   ├── __init__.py
│   │   │   └── gke_provider.py
│   │   ├── google_chat_provider/
│   │   │   ├── __init__.py
│   │   │   └── google_chat_provider.py
│   │   ├── grafana_incident_provider/
│   │   │   ├── __init__.py
│   │   │   └── grafana_incident_provider.py
│   │   ├── grafana_loki_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   ├── docker-compose.auth.yml
│   │   │   └── grafana_loki_provider.py
│   │   ├── grafana_oncall_provider/
│   │   │   ├── __init__.py
│   │   │   └── grafana_oncall_provider.py
│   │   ├── grafana_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   ├── docker-compose.yml
│   │   │   ├── grafana/
│   │   │   │   ├── grafana.ini
│   │   │   │   └── provisioning/
│   │   │   │       ├── access_control/
│   │   │   │       │   └── custom_roles.yml
│   │   │   │       ├── alerting/
│   │   │   │       │   ├── alerts.yml
│   │   │   │       │   ├── contact_points.yml
│   │   │   │       │   └── notification_policies.yml
│   │   │   │       ├── dashboards/
│   │   │   │       │   ├── dashboards.yml
│   │   │   │       │   └── system.json
│   │   │   │       ├── datasources/
│   │   │   │       │   └── datasource.yml
│   │   │   │       ├── notifiers/
│   │   │   │       │   └── email.yml
│   │   │   │       └── service_accounts/
│   │   │   │           ├── service_accounts.yml
│   │   │   │           └── tokens.yml
│   │   │   ├── grafana_alert_format_description.py
│   │   │   ├── grafana_provider.py
│   │   │   └── prometheus/
│   │   │       └── prometheus.yml
│   │   ├── graylog_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   ├── docker-compose-v4.yml
│   │   │   ├── docker-compose.yml
│   │   │   └── graylog_provider.py
│   │   ├── grok_provider/
│   │   │   ├── __init__.py
│   │   │   └── grok_provider.py
│   │   ├── http_provider/
│   │   │   ├── __init__.py
│   │   │   └── http_provider.py
│   │   ├── icinga2_provider/
│   │   │   └── icinga2_provider.py
│   │   ├── ilert_provider/
│   │   │   ├── __init__.py
│   │   │   └── ilert_provider.py
│   │   ├── incidentio_provider/
│   │   │   ├── __init__.py
│   │   │   └── incidentio_provider.py
│   │   ├── incidentmanager_provider/
│   │   │   ├── __init__.py
│   │   │   └── incidentmanager_provider.py
│   │   ├── jira_provider/
│   │   │   ├── __init__.py
│   │   │   └── jira_provider.py
│   │   ├── jiraonprem_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   └── jiraonprem_provider.py
│   │   ├── kafka_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   ├── docker-compose-no-auth.yml
│   │   │   ├── docker-compose.yml
│   │   │   ├── kafka_provider.py
│   │   │   └── kafka_server_jaas.conf
│   │   ├── keep_provider/
│   │   │   ├── __init__.py
│   │   │   └── keep_provider.py
│   │   ├── kibana_provider/
│   │   │   ├── __init__.py
│   │   │   └── kibana_provider.py
│   │   ├── kubernetes_provider/
│   │   │   ├── __init__.py
│   │   │   └── kubernetes_provider.py
│   │   ├── libre_nms_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   └── libre_nms_provider.py
│   │   ├── linear_provider/
│   │   │   ├── __init__.py
│   │   │   └── linear_provider.py
│   │   ├── linearb_provider/
│   │   │   ├── __init__.py
│   │   │   └── linearb_provider.py
│   │   ├── litellm_provider/
│   │   │   ├── __init__.py
│   │   │   └── litellm_provider.py
│   │   ├── llamacpp_provider/
│   │   │   ├── __init__.py
│   │   │   └── llamacpp_provider.py
│   │   ├── mailgun_provider/
│   │   │   ├── __init__.py
│   │   │   └── mailgun_provider.py
│   │   ├── mattermost_provider/
│   │   │   ├── __init__.py
│   │   │   └── mattermost_provider.py
│   │   ├── microsoft-planner-provider/
│   │   │   ├── __init__.py
│   │   │   └── microsoft-planner-provider.py
│   │   ├── mock_provider/
│   │   │   ├── __init__.py
│   │   │   └── mock_provider.py
│   │   ├── models/
│   │   │   ├── __init__.py
│   │   │   ├── provider_config.py
│   │   │   └── provider_method.py
│   │   ├── monday_provider/
│   │   │   ├── __init__.py
│   │   │   └── monday_provider.py
│   │   ├── mongodb_provider/
│   │   │   ├── __init__.py
│   │   │   └── mongodb_provider.py
│   │   ├── mysql_provider/
│   │   │   ├── __init__.py
│   │   │   └── mysql_provider.py
│   │   ├── netbox_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   └── netbox_provider.py
│   │   ├── netdata_provider/
│   │   │   ├── __init__.py
│   │   │   └── netdata_provider.py
│   │   ├── netxms_provider/
│   │   │   ├── __init__.py
│   │   │   └── netxms_provider.py
│   │   ├── newrelic_provider/
│   │   │   ├── __init__.py
│   │   │   └── newrelic_provider.py
│   │   ├── ntfy_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   ├── docker-compose.yml
│   │   │   ├── ntfy_provider.py
│   │   │   └── server.yml
│   │   ├── ollama_provider/
│   │   │   ├── __init__.py
│   │   │   └── ollama_provider.py
│   │   ├── openai_provider/
│   │   │   ├── __init__.py
│   │   │   └── openai_provider.py
│   │   ├── openobserve_provider/
│   │   │   ├── __init__.py
│   │   │   ├── alerttemplate.json
│   │   │   └── openobserve_provider.py
│   │   ├── opensearchserverless_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   └── opensearchserverless_provider.py
│   │   ├── openshift_provider/
│   │   │   ├── __init__.py
│   │   │   └── openshift_provider.py
│   │   ├── opsgenie_provider/
│   │   │   ├── __init__.py
│   │   │   └── opsgenie_provider.py
│   │   ├── pagerduty_provider/
│   │   │   ├── __init__.py
│   │   │   └── pagerduty_provider.py
│   │   ├── pagertree_provider/
│   │   │   ├── __init__.py
│   │   │   └── pagertree_provider.py
│   │   ├── parseable_provider/
│   │   │   ├── __init__.py
│   │   │   └── parseable_provider.py
│   │   ├── pingdom_provider/
│   │   │   ├── __init__.py
│   │   │   └── pingdom_provider.py
│   │   ├── planner_provider/
│   │   │   ├── __init__.py
│   │   │   └── planner_provider.py
│   │   ├── postgres_provider/
│   │   │   ├── __init__.py
│   │   │   └── postgres_provider.py
│   │   ├── posthog_provider/
│   │   │   ├── __init__.py
│   │   │   └── posthog_provider.py
│   │   ├── prometheus_provider/
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   └── prometheus_provider.py
│   │   ├── providers_factory.py
│   │   ├── providers_service.py
│   │   ├── pushover_provider/
│   │   │   ├── __init__.py
│   │   │   └── pushover_provider.py
│   │   ├── python_provider/
│   │   │   ├── __init__.py
│   │   │   └── python_provider.py
│   │   ├── quickchart_provider/
│   │   │   ├── __init__.py
│   │   │   └── quickchart_provider.py
│   │   ├── redmine_provider/
│   │   │   ├── __init__.py
│   │   │   └── redmine_provider.py
│   │   ├── resend_provider/
│   │   │   ├── __init__.py
│   │   │   └── resend_provider.py
│   │   ├── rollbar_provider/
│   │   │   └── rollbar_provider.py
│   │   ├── s3_provider/
│   │   │   ├── __init__.py
│   │   │   └── s3_provider.py
│   │   ├── salesforce_provider/
│   │   │   ├── __init__.py
│   │   │   └── salesforce_provider.py
│   │   ├── sendgrid_provider/
│   │   │   ├── __init__.py
│   │   │   └── sendgrid_provider.py
│   │   ├── sentry_provider/
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   └── sentry_provider.py
│   │   ├── servicenow_provider/
│   │   │   ├── .gitignore
│   │   │   ├── __init__.py
│   │   │   └── servicenow_provider.py
│   │   ├── signalfx_provider/
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   └── signalfx_provider.py
│   │   ├── signl4_provider/
│   │   │   ├── __init__.py
│   │   │   └── signl4_provider.py
│   │   ├── site24x7_provider/
│   │   │   ├── __init__.py
│   │   │   └── site24x7_provider.py
│   │   ├── slack_provider/
│   │   │   ├── __init__.py
│   │   │   └── slack_provider.py
│   │   ├── smtp_provider/
│   │   │   ├── __init__.py
│   │   │   └── smtp_provider.py
│   │   ├── snowflake_provider/
│   │   │   ├── __init__.py
│   │   │   └── snowflake_provider.py
│   │   ├── splunk_provider/
│   │   │   ├── __init__.py
│   │   │   └── splunk_provider.py
│   │   ├── squadcast_provider/
│   │   │   ├── __init__.py
│   │   │   └── squadcast_provider.py
│   │   ├── ssh_provider/
│   │   │   ├── __init__.py
│   │   │   └── ssh_provider.py
│   │   ├── statuscake_provider/
│   │   │   ├── __init__.py
│   │   │   └── statuscake_provider.py
│   │   ├── sumologic_provider/
│   │   │   ├── __init__.py
│   │   │   ├── connection_template.json
│   │   │   └── sumologic_provider.py
│   │   ├── teams_provider/
│   │   │   ├── __init__.py
│   │   │   └── teams_provider.py
│   │   ├── telegram_provider/
│   │   │   ├── __init__.py
│   │   │   └── telegram_provider.py
│   │   ├── thousandeyes_provider/
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   └── thousandeyes_provider.py
│   │   ├── trello_provider/
│   │   │   ├── __init__.py
│   │   │   └── trello_provider.py
│   │   ├── twilio_provider/
│   │   │   └── twilio_provider.py
│   │   ├── uptimekuma_provider/
│   │   │   ├── __init__.py
│   │   │   └── uptimekuma_provider.py
│   │   ├── vectordev_provider/
│   │   │   ├── __init__.py
│   │   │   └── vectordev_provider.py
│   │   ├── victorialogs_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   └── victorialogs_provider.py
│   │   ├── victoriametrics_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   └── victoriametrics_provider.py
│   │   ├── vllm_provider/
│   │   │   ├── __init__.py
│   │   │   └── vllm_provider.py
│   │   ├── wazuh_provider/
│   │   │   ├── __init__.py
│   │   │   ├── alerts_mock.py
│   │   │   ├── custom-keep
│   │   │   ├── custom-keep.py
│   │   │   └── wazuh_provider.py
│   │   ├── webhook_provider/
│   │   │   ├── __init__.py
│   │   │   └── webhook_provider.py
│   │   ├── websocket_provider/
│   │   │   ├── __init__.py
│   │   │   └── websocket_provider.py
│   │   ├── youtrack_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   └── youtrack_provider.py
│   │   ├── zabbix_provider/
│   │   │   ├── README.md
│   │   │   ├── __init__.py
│   │   │   ├── zabbix_provider.py
│   │   │   └── zabbix_provider_script.js
│   │   ├── zendesk_provider/
│   │   │   ├── __init__.py
│   │   │   └── zendesk_provider.py
│   │   ├── zenduty_provider/
│   │   │   ├── __init__.py
│   │   │   └── zenduty_provider.py
│   │   ├── zoom_chat_provider/
│   │   │   ├── __init__.py
│   │   │   └── zoom_chat_provider.py
│   │   └── zoom_provider/
│   │       ├── __init__.py
│   │       └── zoom_provider.py
│   ├── rulesengine/
│   │   ├── __init__.py
│   │   └── rulesengine.py
│   ├── searchengine/
│   │   └── searchengine.py
│   ├── secretmanager/
│   │   ├── __init__.py
│   │   ├── awssecretmanager.py
│   │   ├── dbsecretmanager.py
│   │   ├── filesecretmanager.py
│   │   ├── gcpsecretmanager.py
│   │   ├── kubernetessecretmanager.py
│   │   ├── secretmanager.py
│   │   ├── secretmanagerfactory.py
│   │   └── vaultsecretmanager.py
│   ├── server_jobs_bg.py
│   ├── step/
│   │   ├── __init__.py
│   │   ├── step.py
│   │   └── step_provider_parameter.py
│   ├── throttles/
│   │   ├── base_throttle.py
│   │   ├── one_until_resolved_throttle.py
│   │   └── throttle_factory.py
│   ├── topologies/
│   │   ├── topologies_service.py
│   │   └── topology_processor.py
│   ├── validation/
│   │   ├── __init__.py
│   │   └── fields.py
│   └── workflowmanager/
│       ├── __init__.py
│       ├── workflow.py
│       ├── workflowmanager.py
│       ├── workflowscheduler.py
│       └── workflowstore.py
├── keep-ui/
│   ├── .dockerignore
│   ├── .eslintignore
│   ├── .eslintrc.json
│   ├── .gitignore
│   ├── .prettierrc
│   ├── README.md
│   ├── __mocks__/
│   │   ├── @monaco-editor/
│   │   │   └── react.js
│   │   └── monaco-editor.js
│   ├── app/
│   │   ├── (health)/
│   │   │   ├── health/
│   │   │   │   ├── check.tsx
│   │   │   │   ├── modal.tsx
│   │   │   │   └── page.tsx
│   │   │   └── layout.tsx
│   │   ├── (keep)/
│   │   │   ├── [...not-found]/
│   │   │   │   └── page.tsx
│   │   │   ├── ai/
│   │   │   │   ├── ai-plugins.tsx
│   │   │   │   ├── model.ts
│   │   │   │   └── page.tsx
│   │   │   ├── alerts/
│   │   │   │   └── [id]/
│   │   │   │       ├── page.tsx
│   │   │   │       └── ui/
│   │   │   │           ├── __tests__/
│   │   │   │           │   └── alerts-fingerprint.test.tsx
│   │   │   │           ├── alert-table-alert-facets.tsx
│   │   │   │           ├── alert-table-facet-dynamic.tsx
│   │   │   │           ├── alert-table-facet-types.tsx
│   │   │   │           ├── alert-table-facet-utils.tsx
│   │   │   │           ├── alert-table-facet-value.tsx
│   │   │   │           ├── alert-table-facet.tsx
│   │   │   │           ├── alert-table-tab-panel-server-side.tsx
│   │   │   │           └── alerts.tsx
│   │   │   ├── dashboard/
│   │   │   │   ├── GridItem.tsx
│   │   │   │   ├── GridItemContainer.tsx
│   │   │   │   ├── GridLayout.tsx
│   │   │   │   ├── MenuButton.tsx
│   │   │   │   ├── WidgetModal.tsx
│   │   │   │   ├── [id]/
│   │   │   │   │   ├── dashboard.tsx
│   │   │   │   │   └── page.tsx
│   │   │   │   ├── alert-quality-table.tsx
│   │   │   │   ├── styles.css
│   │   │   │   ├── types.tsx
│   │   │   │   └── widget-types/
│   │   │   │       ├── generic-metrics/
│   │   │   │       │   ├── generic-metrics-grid-item.tsx
│   │   │   │       │   └── generic-metrics-widget-form.tsx
│   │   │   │       ├── metric/
│   │   │   │       │   ├── metric-grid-item.tsx
│   │   │   │       │   └── metric-widget-form.tsx
│   │   │   │       └── preset/
│   │   │   │           ├── columns-selection.tsx
│   │   │   │           ├── constants.ts
│   │   │   │           ├── preset-grid-item.tsx
│   │   │   │           ├── preset-widget-form.tsx
│   │   │   │           ├── widget-alert-count-panel.tsx
│   │   │   │           └── widget-alerts-table.tsx
│   │   │   ├── deduplication/
│   │   │   │   ├── DeduplicationPlaceholder.tsx
│   │   │   │   ├── DeduplicationSidebar.tsx
│   │   │   │   ├── DeduplicationTable.tsx
│   │   │   │   ├── client.tsx
│   │   │   │   ├── models.tsx
│   │   │   │   └── page.tsx
│   │   │   ├── error.ts
│   │   │   ├── extraction/
│   │   │   │   ├── [rule_id]/
│   │   │   │   │   └── executions/
│   │   │   │   │       ├── [execution_id]/
│   │   │   │   │       │   └── page.tsx
│   │   │   │   │       └── page.tsx
│   │   │   │   ├── create-or-update-extraction-rule.tsx
│   │   │   │   ├── extraction.tsx
│   │   │   │   ├── extractions-table.tsx
│   │   │   │   ├── layout.tsx
│   │   │   │   ├── model.ts
│   │   │   │   ├── page.tsx
│   │   │   │   └── run-extraction-modal.tsx
│   │   │   ├── incidents/
│   │   │   │   ├── [id]/
│   │   │   │   │   ├── activity/
│   │   │   │   │   │   ├── incident-activity.css
│   │   │   │   │   │   ├── incident-activity.tsx
│   │   │   │   │   │   ├── lib/
│   │   │   │   │   │   │   └── extractTaggedUsers.ts
│   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   └── ui/
│   │   │   │   │   │       ├── IncidentActivityComment.tsx
│   │   │   │   │   │       ├── IncidentActivityItem.tsx
│   │   │   │   │   │       ├── IncidentCommentInput.dynamic.tsx
│   │   │   │   │   │       ├── IncidentCommentInput.scss
│   │   │   │   │   │       └── IncidentCommentInput.tsx
│   │   │   │   │   ├── alerts/
│   │   │   │   │   │   ├── ALERT_SIDEBAR_INTEGRATION.md
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── incident-alerts-sidebar.test.tsx
│   │   │   │   │   │   │   └── incident-alerts.test.tsx
│   │   │   │   │   │   ├── incident-alert-action-tray.tsx
│   │   │   │   │   │   ├── incident-alert-actions.tsx
│   │   │   │   │   │   ├── incident-alert-table-body-skeleton.tsx
│   │   │   │   │   │   ├── incident-alerts.tsx
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   ├── chat/
│   │   │   │   │   │   ├── incident-chat.css
│   │   │   │   │   │   ├── incident-chat.tsx
│   │   │   │   │   │   └── page.client.tsx
│   │   │   │   │   ├── create-ticket-modal.tsx
│   │   │   │   │   ├── enrichments/
│   │   │   │   │   │   ├── EnrichmentEditableField.tsx
│   │   │   │   │   │   └── EnrichmentEditableForm.tsx
│   │   │   │   │   ├── getIncidentWithErrorHandling.tsx
│   │   │   │   │   ├── incident-header-skeleton.tsx
│   │   │   │   │   ├── incident-header.tsx
│   │   │   │   │   ├── incident-layout-client.tsx
│   │   │   │   │   ├── incident-overview.tsx
│   │   │   │   │   ├── incident-tabs-navigation.tsx
│   │   │   │   │   ├── layout.tsx
│   │   │   │   │   ├── link-ticket-modal.tsx
│   │   │   │   │   ├── not-found.tsx
│   │   │   │   │   ├── route.tsx
│   │   │   │   │   ├── ticketing-incident-options.tsx
│   │   │   │   │   ├── timeline/
│   │   │   │   │   │   ├── incident-timeline.tsx
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   ├── topology/
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   └── workflows/
│   │   │   │   │       ├── incident-workflow-empty.tsx
│   │   │   │   │       ├── incident-workflow-sidebar.tsx
│   │   │   │   │       ├── incident-workflow-table.tsx
│   │   │   │   │       └── page.tsx
│   │   │   │   ├── incident-overview-skeleton.tsx
│   │   │   │   ├── layout.tsx
│   │   │   │   ├── page.tsx
│   │   │   │   └── predicted-incidents-table.tsx
│   │   │   ├── layout.tsx
│   │   │   ├── loading.tsx
│   │   │   ├── maintenance/
│   │   │   │   ├── create-or-update-maintenance-rule.tsx
│   │   │   │   ├── layout.tsx
│   │   │   │   ├── maintenance-rules-table.tsx
│   │   │   │   ├── maintenance.tsx
│   │   │   │   ├── model.ts
│   │   │   │   └── page.tsx
│   │   │   ├── mapping/
│   │   │   │   ├── [rule_id]/
│   │   │   │   │   └── executions/
│   │   │   │   │       ├── [execution_id]/
│   │   │   │   │       │   └── page.tsx
│   │   │   │   │       └── page.tsx
│   │   │   │   ├── create-or-edit-mapping.tsx
│   │   │   │   ├── layout.tsx
│   │   │   │   ├── mapping.tsx
│   │   │   │   ├── models.tsx
│   │   │   │   ├── page.tsx
│   │   │   │   ├── rules-table.tsx
│   │   │   │   └── run-mapping-modal.tsx
│   │   │   ├── not-found.tsx
│   │   │   ├── notifications-hub/
│   │   │   │   ├── layout.tsx
│   │   │   │   └── page.tsx
│   │   │   ├── page.tsx
│   │   │   ├── providers/
│   │   │   │   ├── components/
│   │   │   │   │   ├── providers-categories/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── providers-categories.tsx
│   │   │   │   │   ├── providers-filter-by-label/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── providers-filter-by-label.tsx
│   │   │   │   │   └── providers-search/
│   │   │   │   │       ├── index.ts
│   │   │   │   │       └── providers-search.tsx
│   │   │   │   ├── filter-context/
│   │   │   │   │   ├── constants.ts
│   │   │   │   │   ├── filter-context.tsx
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── types.ts
│   │   │   │   │   └── use-filter-context.ts
│   │   │   │   ├── form-fields.tsx
│   │   │   │   ├── form-validation.ts
│   │   │   │   ├── layout.tsx
│   │   │   │   ├── oauth2/
│   │   │   │   │   └── [providerType]/
│   │   │   │   │       └── page.tsx
│   │   │   │   ├── page.client.tsx
│   │   │   │   ├── page.tsx
│   │   │   │   ├── provider-form-scopes.css
│   │   │   │   ├── provider-form-scopes.tsx
│   │   │   │   ├── provider-form.css
│   │   │   │   ├── provider-form.tsx
│   │   │   │   ├── provider-logs.tsx
│   │   │   │   ├── provider-semi-automated.tsx
│   │   │   │   ├── provider-tile.css
│   │   │   │   ├── provider-tile.tsx
│   │   │   │   ├── providers-tiles.tsx
│   │   │   │   └── providers.css
│   │   │   ├── rules/
│   │   │   │   ├── CorrelationPlaceholder.tsx
│   │   │   │   ├── CorrelationSidebar/
│   │   │   │   │   ├── AlertsFoundBadge.tsx
│   │   │   │   │   ├── CorrelationForm.tsx
│   │   │   │   │   ├── CorrelationGroups.tsx
│   │   │   │   │   ├── CorrelationSidebarBody.tsx
│   │   │   │   │   ├── CorrelationSidebarHeader.tsx
│   │   │   │   │   ├── CorrelationSubmission.tsx
│   │   │   │   │   ├── DeleteRule.tsx
│   │   │   │   │   ├── RuleFields.tsx
│   │   │   │   │   ├── RuleGroup.tsx
│   │   │   │   │   ├── convert-cel-ast-to-query-builder-ast/
│   │   │   │   │   │   ├── convert-cel-ast-to-query-builder-ast.function.test.ts
│   │   │   │   │   │   └── convert-cel-ast-to-query-builder-ast.function.ts
│   │   │   │   │   ├── index.tsx
│   │   │   │   │   ├── timeframe-constants.ts
│   │   │   │   │   ├── types.ts
│   │   │   │   │   └── useMatchingAlerts.ts
│   │   │   │   ├── CorrelationTable.tsx
│   │   │   │   ├── GroupedByCel.tsx
│   │   │   │   ├── client.tsx
│   │   │   │   ├── flatten-cel-ast.ts
│   │   │   │   ├── page.tsx
│   │   │   │   └── ui/
│   │   │   │       └── PlaceholderSankey.tsx
│   │   │   ├── settings/
│   │   │   │   ├── auth/
│   │   │   │   │   ├── api-key-settings.tsx
│   │   │   │   │   ├── api-key-tab.tsx
│   │   │   │   │   ├── api-key-table.tsx
│   │   │   │   │   ├── groups-sidebar.tsx
│   │   │   │   │   ├── groups-tab.tsx
│   │   │   │   │   ├── groups-table.tsx
│   │   │   │   │   ├── multiselect.css
│   │   │   │   │   ├── permissions-sidebar.tsx
│   │   │   │   │   ├── permissions-tab.tsx
│   │   │   │   │   ├── permissions-table.tsx
│   │   │   │   │   ├── roles-sidebar.tsx
│   │   │   │   │   ├── roles-tab.tsx
│   │   │   │   │   ├── roles-table.tsx
│   │   │   │   │   ├── sso-settings.tsx
│   │   │   │   │   ├── sso-tab.tsx
│   │   │   │   │   ├── types.ts
│   │   │   │   │   ├── users-settings.tsx
│   │   │   │   │   ├── users-sidebar.tsx
│   │   │   │   │   ├── users-tab.tsx
│   │   │   │   │   └── users-table.tsx
│   │   │   │   ├── create-api-key-modal.tsx
│   │   │   │   ├── layout.tsx
│   │   │   │   ├── models.tsx
│   │   │   │   ├── page.tsx
│   │   │   │   ├── provider-images/
│   │   │   │   │   ├── page.tsx
│   │   │   │   │   ├── provider-image-list.tsx
│   │   │   │   │   ├── provider-image-uploader.tsx
│   │   │   │   │   └── provider-images-settings.tsx
│   │   │   │   ├── settings.client.tsx
│   │   │   │   ├── smtp-settings.tsx
│   │   │   │   └── webhook-settings.tsx
│   │   │   ├── topology/
│   │   │   │   ├── TopologySearchContext.tsx
│   │   │   │   ├── api/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── layout.tsx
│   │   │   │   ├── lib/
│   │   │   │   │   └── badge-colors.ts
│   │   │   │   ├── model/
│   │   │   │   │   ├── TopologyPollingContext.tsx
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── models.ts
│   │   │   │   │   ├── useTopology.ts
│   │   │   │   │   └── useTopologyApplications.ts
│   │   │   │   ├── page.tsx
│   │   │   │   ├── topology-client.tsx
│   │   │   │   └── ui/
│   │   │   │       ├── TopologySearchAutocomplete.tsx
│   │   │   │       ├── applications/
│   │   │   │       │   ├── application-card.tsx
│   │   │   │       │   ├── application-modal.tsx
│   │   │   │       │   ├── applications-list.tsx
│   │   │   │       │   └── create-or-update-application-form.tsx
│   │   │   │       └── map/
│   │   │   │           ├── AddEditNodeSidePanel.tsx
│   │   │   │           ├── application-node.tsx
│   │   │   │           ├── getLayoutedElements.ts
│   │   │   │           ├── getNodesAndEdgesFromTopologyData.ts
│   │   │   │           ├── index.tsx
│   │   │   │           ├── manage-selection.tsx
│   │   │   │           ├── service-node.tsx
│   │   │   │           ├── styles.tsx
│   │   │   │           ├── topology-map.tsx
│   │   │   │           └── topology.css
│   │   │   └── workflows/
│   │   │       ├── [workflow_id]/
│   │   │       │   ├── layout.tsx
│   │   │       │   ├── page.tsx
│   │   │       │   ├── runs/
│   │   │       │   │   └── [workflow_execution_id]/
│   │   │       │   │       └── page.tsx
│   │   │       │   ├── table-filters.tsx
│   │   │       │   ├── versions/
│   │   │       │   │   └── [revision]/
│   │   │       │   │       └── page.tsx
│   │   │       │   ├── workflow-breadcrumbs.tsx
│   │   │       │   ├── workflow-detail-header.tsx
│   │   │       │   ├── workflow-detail-page.tsx
│   │   │       │   ├── workflow-executions-table.tsx
│   │   │       │   ├── workflow-overview-skeleton.tsx
│   │   │       │   ├── workflow-overview.tsx
│   │   │       │   ├── workflow-providers.tsx
│   │   │       │   ├── workflow-secrets.tsx
│   │   │       │   ├── workflow-sync-status.tsx
│   │   │       │   └── workflow-versions.tsx
│   │   │       ├── __tests__/
│   │   │       │   └── existing-workflows-state.test.tsx
│   │   │       ├── builder/
│   │   │       │   ├── [workflowId]/
│   │   │       │   │   └── page.tsx
│   │   │       │   ├── layout.tsx
│   │   │       │   └── page.tsx
│   │   │       ├── create-workflow-modal.tsx
│   │   │       ├── existing-workflows-state.tsx
│   │   │       ├── no-workflows-state.tsx
│   │   │       ├── noworkflows.tsx
│   │   │       ├── page.tsx
│   │   │       ├── preview/
│   │   │       │   ├── [workflowId]/
│   │   │       │   │   └── page.tsx
│   │   │       │   └── page.tsx
│   │   │       ├── upload-workflows-modal.tsx
│   │   │       ├── workflow-graph.tsx
│   │   │       ├── workflow-menu.tsx
│   │   │       ├── workflow-templates/
│   │   │       │   ├── index.ts
│   │   │       │   ├── workflow-template-card.tsx
│   │   │       │   └── workflow-templates.tsx
│   │   │       ├── workflow-tile.css
│   │   │       ├── workflow-tile.tsx
│   │   │       ├── workflow-utils.ts
│   │   │       ├── workflows-steps.tsx
│   │   │       └── workflows.page.tsx
│   │   ├── (signin)/
│   │   │   ├── error/
│   │   │   │   ├── authEnvUtils.tsx
│   │   │   │   ├── error-client.tsx
│   │   │   │   └── page.tsx
│   │   │   ├── layout.tsx
│   │   │   ├── mobile/
│   │   │   │   ├── GithubButton.tsx
│   │   │   │   └── page.tsx
│   │   │   └── signin/
│   │   │       ├── SignInForm.tsx
│   │   │       └── page.tsx
│   │   ├── actions/
│   │   │   └── authactions.ts
│   │   ├── api/
│   │   │   ├── auth/
│   │   │   │   └── [...nextauth]/
│   │   │   │       └── route.ts
│   │   │   ├── aws-marketplace/
│   │   │   │   └── route.ts
│   │   │   ├── copilotkit/
│   │   │   │   └── route.ts
│   │   │   └── healthcheck/
│   │   │       └── route.ts
│   │   ├── auth-provider.tsx
│   │   ├── config-provider.tsx
│   │   ├── global-error.tsx
│   │   ├── globals.css
│   │   ├── not-authorized.tsx
│   │   ├── posthog-provider.tsx
│   │   └── raw/
│   │       └── workflows/
│   │           └── [workflow_filename]/
│   │               └── route.ts
│   ├── auth.config.ts
│   ├── auth.ts
│   ├── components/
│   │   ├── LinkWithIcon.tsx
│   │   ├── LogViewer.tsx
│   │   ├── SidePanel.tsx
│   │   ├── banners/
│   │   │   ├── BannerBase.tsx
│   │   │   ├── health-page-banner.tsx
│   │   │   └── read-only-banner.tsx
│   │   ├── filters/
│   │   │   └── GenericFilters.tsx
│   │   ├── icons/
│   │   │   └── index.tsx
│   │   ├── navbar/
│   │   │   ├── AILink.tsx
│   │   │   ├── AlertsLinks.tsx
│   │   │   ├── DashboardLink.tsx
│   │   │   ├── DashboardLinks.tsx
│   │   │   ├── IncidentLinks.tsx
│   │   │   ├── Menu.tsx
│   │   │   ├── MinimizeMenuButton.tsx
│   │   │   ├── Navbar.css
│   │   │   ├── Navbar.tsx
│   │   │   ├── NoiseReductionLinks.tsx
│   │   │   ├── Search.tsx
│   │   │   ├── SetSentryUser.tsx
│   │   │   ├── UserAvatar.tsx
│   │   │   └── UserInfo.tsx
│   │   ├── popover/
│   │   │   └── GenericPopover.tsx
│   │   ├── table/
│   │   │   ├── ExecutionsTable.tsx
│   │   │   ├── GenericTable.tsx
│   │   │   └── Pagination.tsx
│   │   └── ui/
│   │       ├── AutocompleteInput.tsx
│   │       ├── Button.tsx
│   │       ├── Calendar.scss
│   │       ├── Calendar.tsx
│   │       ├── CreatableMultiSelect.tsx
│   │       ├── DateRangePicker.tsx
│   │       ├── DateRangePickerV2.tsx
│   │       ├── DynamicProviderIcon.tsx
│   │       ├── EmptyStateImage.tsx
│   │       ├── EmptyStateTable.tsx
│   │       ├── ImagePreviewTooltip.tsx
│   │       ├── Link.tsx
│   │       ├── Modal.tsx
│   │       ├── ResizableColumns.tsx
│   │       ├── RootCauseAnalysis.tsx
│   │       ├── ShortNumber.tsx
│   │       ├── TextInput.tsx
│   │       ├── Textarea.tsx
│   │       ├── index.ts
│   │       └── useTimeframeState.ts
│   ├── docs/
│   │   └── incident-alerts/
│   │       ├── ALERT_SIDEBAR_INTEGRATION.md
│   │       └── CI_CD_FIXES.md
│   ├── entities/
│   │   ├── alerts/
│   │   │   ├── lib/
│   │   │   │   └── getTabsFromPreset.ts
│   │   │   ├── model/
│   │   │   │   ├── constants.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── types.ts
│   │   │   │   ├── useAlertRowStyle.ts
│   │   │   │   ├── useAlertTableTheme.ts
│   │   │   │   ├── useAlerts.ts
│   │   │   │   ├── useAvailableAlertFields.ts
│   │   │   │   └── useSeverityMapping.ts
│   │   │   └── ui/
│   │   │       ├── AlertImage/
│   │   │       │   └── AlertImage.tsx
│   │   │       ├── AlertName/
│   │   │       │   └── AlertName.tsx
│   │   │       ├── alert-severity.tsx
│   │   │       └── index.ts
│   │   ├── incidents/
│   │   │   ├── api/
│   │   │   │   ├── incidents.ts
│   │   │   │   └── index.ts
│   │   │   ├── lib/
│   │   │   │   ├── __tests__/
│   │   │   │   │   └── ticketing-utils.test.ts
│   │   │   │   ├── ticketing-utils.ts
│   │   │   │   └── utils.ts
│   │   │   ├── model/
│   │   │   │   ├── index.ts
│   │   │   │   ├── models.ts
│   │   │   │   └── useIncidentActions.tsx
│   │   │   └── ui/
│   │   │       ├── IncidentIconName/
│   │   │       │   ├── IncidentIconName.tsx
│   │   │       │   └── index.ts
│   │   │       ├── IncidentSeverityBadge.tsx
│   │   │       ├── index.ts
│   │   │       └── statuses.tsx
│   │   ├── presets/
│   │   │   └── model/
│   │   │       ├── constants.ts
│   │   │       ├── index.ts
│   │   │       ├── types.ts
│   │   │       ├── usePresetActions.ts
│   │   │       ├── usePresetColumnConfig.ts
│   │   │       ├── usePresetColumnState.ts
│   │   │       ├── usePresetPolling.ts
│   │   │       ├── usePresets.ts
│   │   │       └── useSilencedPresets.ts
│   │   ├── provider-images/
│   │   │   └── model/
│   │   │       └── useProviderImages.ts
│   │   ├── providers/
│   │   │   └── model/
│   │   │       └── __mocks__/
│   │   │           └── provider-mocks.ts
│   │   ├── users/
│   │   │   ├── model/
│   │   │   │   ├── useUser.ts
│   │   │   │   └── useUsers.ts
│   │   │   └── ui/
│   │   │       ├── UserStatefulAvatar.tsx
│   │   │       └── index.ts
│   │   ├── workflow-executions/
│   │   │   └── model/
│   │   │       ├── __tests__/
│   │   │       │   └── useWorkflowExecutionsV2.test.tsx
│   │   │       ├── index.ts
│   │   │       ├── useWorkflowExecutionDetail.ts
│   │   │       ├── useWorkflowExecutions.ts
│   │   │       ├── useWorkflowExecutionsRevalidation.ts
│   │   │       ├── useWorkflowExecutionsV2.ts
│   │   │       └── workflowExecutionsKeys.ts
│   │   └── workflows/
│   │       ├── index.ts
│   │       ├── lib/
│   │       │   ├── __tests__/
│   │       │   │   ├── extractWorkflowYamlDependencies.test.ts
│   │       │   │   ├── getCurrentPath.test.ts
│   │       │   │   ├── mustache.test.ts
│   │       │   │   ├── parseWorkflowYamlToJSON.test.ts
│   │       │   │   ├── parser.test.ts
│   │       │   │   ├── validate-mustache-ui-builder.test.ts
│   │       │   │   ├── validate-mustache-yaml.test.ts
│   │       │   │   ├── validation.test.ts
│   │       │   │   └── yaml-utils.test.ts
│   │       │   ├── extractWorkflowYamlDependencies.ts
│   │       │   ├── generateWorkflowYamlJsonSchema.ts
│   │       │   ├── getHumanReadableInterval.ts
│   │       │   ├── getLayoutedWorkflowElements.ts
│   │       │   ├── getTriggerDescription.ts
│   │       │   ├── mustache.ts
│   │       │   ├── parser.ts
│   │       │   ├── ui-utils.tsx
│   │       │   ├── use-query-workflow-template.ts
│   │       │   ├── useWorkflowJsonSchema.ts
│   │       │   ├── useWorkflowZodSchema.ts
│   │       │   ├── validate-definition.ts
│   │       │   ├── validate-mustache-ui-builder.ts
│   │       │   ├── validate-mustache-yaml.ts
│   │       │   └── yaml-utils.ts
│   │       ├── model/
│   │       │   ├── __mocks__/
│   │       │   │   └── mock-workflow.ts
│   │       │   ├── __tests__/
│   │       │   │   ├── types.test.ts
│   │       │   │   ├── useWorkflowActions.test.ts
│   │       │   │   ├── useWorkflowRevalidation.test.tsx
│   │       │   │   ├── useWorkflowsV2.test.ts
│   │       │   │   ├── workflow-store.test.tsx
│   │       │   │   └── yaml.schema.test.ts
│   │       │   ├── index.ts
│   │       │   ├── schema.ts
│   │       │   ├── types.ts
│   │       │   ├── useWorkflowActions.ts
│   │       │   ├── useWorkflowDetail.ts
│   │       │   ├── useWorkflowRevalidation.ts
│   │       │   ├── useWorkflowRevisions.ts
│   │       │   ├── useWorkflows.ts
│   │       │   ├── useWorkflowsV2.ts
│   │       │   ├── workflow-store.ts
│   │       │   ├── workflow-yaml-editor-store.ts
│   │       │   ├── workflowKeys.ts
│   │       │   ├── yaml.schema.ts
│   │       │   └── yaml.types.ts
│   │       └── ui/
│   │           ├── NodeTriggerIcon.tsx
│   │           ├── TriggerIcon.tsx
│   │           ├── WorkflowAlertIncidentDependenciesForm.tsx
│   │           ├── WorkflowInputFields.tsx
│   │           ├── WorkflowPermissionsBadge.tsx
│   │           └── WorkflowTriggerBadge.tsx
│   ├── entrypoint.sh
│   ├── errors.ts
│   ├── eslint.config.mjs
│   ├── features/
│   │   ├── alerts/
│   │   │   ├── alert-assign-ticket/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       └── alert-assign-ticket-modal.tsx
│   │   │   ├── alert-associate-to-incident/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       └── alert-associate-incident-modal.tsx
│   │   │   ├── alert-call-provider-method/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       ├── alert-method-modal.tsx
│   │   │   │       └── alert-method-results-table.tsx
│   │   │   ├── alert-change-status/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       └── alert-change-status-modal.tsx
│   │   │   ├── alert-create-incident-ai/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       ├── alert-create-incident-ai-card.tsx
│   │   │   │       └── alert-create-incident-ai-modal.tsx
│   │   │   ├── alert-detail-sidebar/
│   │   │   │   ├── index.ts
│   │   │   │   ├── lib/
│   │   │   │   │   └── alertSidebarFields.tsx
│   │   │   │   └── ui/
│   │   │   │       ├── alert-sidebar-incidents.tsx
│   │   │   │       ├── alert-sidebar.tsx
│   │   │   │       └── alert-timeline.tsx
│   │   │   ├── alert-error-event-process/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       └── alert-error-event-modal.tsx
│   │   │   ├── alert-history/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       ├── alert-history-charts.tsx
│   │   │   │       └── alert-history-modal.tsx
│   │   │   ├── alert-menu/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       └── alert-menu.tsx
│   │   │   ├── alert-note/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       └── alert-note-modal.tsx
│   │   │   ├── change-alert-table-theme/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       ├── AlertTableThemeSelection.tsx
│   │   │   │       └── __tests__/
│   │   │   │           └── change-alert-table-theme.test.tsx
│   │   │   ├── dismiss-alert/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       ├── alert-dismiss-modal.css
│   │   │   │       └── alert-dismiss-modal.tsx
│   │   │   ├── enrich-alert/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       └── EnrichAlertSidePanel.tsx
│   │   │   ├── severity-mapping/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       ├── SeverityMappingFacet.tsx
│   │   │   │       └── SeverityMappingSelection.tsx
│   │   │   ├── simulate-alert/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       └── alert-push-alert-to-server-modal.tsx
│   │   │   └── view-raw-alert/
│   │   │       ├── index.ts
│   │   │       └── ui/
│   │   │           ├── ViewAlertModal.css
│   │   │           └── ViewAlertModal.tsx
│   │   ├── cel-input/
│   │   │   ├── __tests__/
│   │   │   │   └── use-cel-state.test.ts
│   │   │   ├── cel-input.tsx
│   │   │   └── use-cel-state.ts
│   │   ├── filter/
│   │   │   ├── add-facet-modal-with-suggestions.tsx
│   │   │   ├── add-facet-modal.tsx
│   │   │   ├── api.ts
│   │   │   ├── facet-panel-server-side.tsx
│   │   │   ├── facet-value.tsx
│   │   │   ├── facet.tsx
│   │   │   ├── facets-panel.tsx
│   │   │   ├── hooks.tsx
│   │   │   ├── index.ts
│   │   │   ├── models.tsx
│   │   │   ├── pagination.tsx
│   │   │   ├── search-input.tsx
│   │   │   └── store/
│   │   │       ├── __tests__/
│   │   │       │   ├── facets-store.test.ts
│   │   │       │   ├── use-initial-state-handler.test.ts
│   │   │       │   ├── use-queries-handler.test.ts
│   │   │       │   └── utils.test.ts
│   │   │       ├── create-facets-store.ts
│   │   │       ├── index.ts
│   │   │       ├── use-facets-config.tsx
│   │   │       ├── use-facets-loading-state-handler.ts
│   │   │       ├── use-initial-state-handler.ts
│   │   │       ├── use-queries-handler.ts
│   │   │       ├── use-query-params/
│   │   │       │   ├── __tests__/
│   │   │       │   │   ├── split-facet-values.test.ts
│   │   │       │   │   └── use-query-params.test.ts
│   │   │       │   ├── split-facet-values.ts
│   │   │       │   └── use-query-params.ts
│   │   │       ├── use-store.tsx
│   │   │       └── utils.ts
│   │   ├── incidents/
│   │   │   ├── change-incident-severity/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       ├── incident-change-severity-select.tsx
│   │   │   │       └── incident-severity-select.tsx
│   │   │   ├── change-incident-status/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       └── incident-change-status-select.tsx
│   │   │   ├── create-or-update-incident/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       ├── create-or-update-incident-form.tsx
│   │   │   │       └── react-quill-override.css
│   │   │   ├── incident-list/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       ├── incident-dropdown-menu.tsx
│   │   │   │       ├── incident-list-error.tsx
│   │   │   │       ├── incident-list-placeholder.tsx
│   │   │   │       ├── incident-list.tsx
│   │   │   │       ├── incident-table-component.tsx
│   │   │   │       ├── incident-table-filters-context.tsx
│   │   │   │       ├── incidents-not-found.tsx
│   │   │   │       ├── incidents-report/
│   │   │   │       │   ├── generate-report-modal.tsx
│   │   │   │       │   ├── incident-severity-metric.tsx
│   │   │   │       │   ├── incidents-report.tsx
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── models.ts
│   │   │   │       │   ├── pie-chart.tsx
│   │   │   │       │   └── use-report-data.ts
│   │   │   │       ├── incidents-table.tsx
│   │   │   │       └── useIncidentsTableData.tsx
│   │   │   ├── merge-incidents/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       └── merge-incidents-modal.tsx
│   │   │   ├── same-incidents-in-the-past/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       ├── change-same-incident-in-the-past-form.tsx
│   │   │   │       ├── following-incidents.tsx
│   │   │   │       ├── index.ts
│   │   │   │       └── same-incident-field.tsx
│   │   │   └── split-incident-alerts/
│   │   │       ├── index.ts
│   │   │       └── ui/
│   │   │           └── split-incident-alerts-modal.tsx
│   │   ├── keyboard-shortcuts/
│   │   │   ├── index.ts
│   │   │   └── useIsShiftKeyHeld.ts
│   │   ├── presets/
│   │   │   ├── create-or-update-preset/
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       ├── alerts-count-badge.tsx
│   │   │   │       ├── create-or-update-preset-form.tsx
│   │   │   │       └── preset-controls.tsx
│   │   │   ├── custom-preset-links/
│   │   │   │   ├── index.ts
│   │   │   │   ├── model/
│   │   │   │   │   └── usePresetAlertsCount.ts
│   │   │   │   └── ui/
│   │   │   │       ├── CustomPresetAlertLink.css
│   │   │   │       ├── CustomPresetAlertLinks.tsx
│   │   │   │       └── PresetsNoise.tsx
│   │   │   └── presets-manager/
│   │   │       ├── index.ts
│   │   │       ├── lib/
│   │   │       │   └── eval-with-context.ts
│   │   │       └── ui/
│   │   │           ├── __tests__/
│   │   │           │   ├── alert-preset-manager.test.tsx
│   │   │           │   └── preset-navigation.test.ts
│   │   │           ├── alert-preset-manager.tsx
│   │   │           └── alerts-rules-builder.tsx
│   │   ├── workflow-execution-results/
│   │   │   ├── index.ts
│   │   │   ├── lib/
│   │   │   │   └── logs-utils.ts
│   │   │   └── ui/
│   │   │       ├── WorkflowExecutionError.tsx
│   │   │       ├── WorkflowExecutionLogs.tsx
│   │   │       └── WorkflowExecutionResults.tsx
│   │   └── workflows/
│   │       ├── ai-assistant/
│   │       │   ├── index.ts
│   │       │   ├── lib/
│   │       │   │   ├── constants.ts
│   │       │   │   └── utils.ts
│   │       │   └── ui/
│   │       │       ├── AddStepUI.tsx
│   │       │       ├── AddTriggerOrStepSkeleton.tsx
│   │       │       ├── AddTriggerUI.tsx
│   │       │       ├── StepPreview.tsx
│   │       │       ├── SuggestionStatus.tsx
│   │       │       ├── WorkflowBuilderChat.tsx
│   │       │       ├── WorkflowBuilderChatSafe.tsx
│   │       │       └── chat.css
│   │       ├── builder/
│   │       │   ├── index.ts
│   │       │   ├── lib/
│   │       │   │   └── utils.tsx
│   │       │   └── ui/
│   │       │       ├── Editor/
│   │       │       │   ├── EditorField.tsx
│   │       │       │   ├── ReactFlowEditor.tsx
│   │       │       │   ├── StepEditor.tsx
│   │       │       │   ├── StepTest.tsx
│   │       │       │   ├── TriggerEditor.tsx
│   │       │       │   └── WorkflowEditor.tsx
│   │       │       ├── NodeMenu.tsx
│   │       │       ├── ReactFlowBuilder.tsx
│   │       │       ├── WorkflowEdge.tsx
│   │       │       ├── WorkflowNode.tsx
│   │       │       ├── WorkflowToolbox.tsx
│   │       │       ├── __tests__/
│   │       │       │   └── ReactFlowBuilder.test.tsx
│   │       │       └── workflow-status.tsx
│   │       ├── edit-metadata/
│   │       │   ├── index.ts
│   │       │   └── ui/
│   │       │       ├── edit-workflow-metadata-form.tsx
│   │       │       └── workflow-metadata-modal.tsx
│   │       ├── edit-workflow-metadata/
│   │       │   ├── index.ts
│   │       │   └── ui/
│   │       │       └── edit-workflow-metadata-form.tsx
│   │       ├── enable-disable/
│   │       │   ├── index.ts
│   │       │   ├── model/
│   │       │   │   ├── index.ts
│   │       │   │   └── useWorkflowToggle.ts
│   │       │   └── ui/
│   │       │       └── WorkflowEnabledSwitch.tsx
│   │       ├── manual-run-workflow/
│   │       │   ├── index.ts
│   │       │   ├── model/
│   │       │   │   ├── WorkflowModalContext.tsx
│   │       │   │   ├── types.ts
│   │       │   │   └── useWorkflowRun.ts
│   │       │   └── ui/
│   │       │       ├── WorkflowInputsForm.tsx
│   │       │       ├── WorkflowUnsavedChangesForm.tsx
│   │       │       ├── manual-run-workflow-modal.tsx
│   │       │       └── workflow-run-with-alert-modal.tsx
│   │       └── test-run/
│   │           ├── index.ts
│   │           ├── model/
│   │           │   └── useWorkflowTestRun.ts
│   │           └── ui/
│   │               └── workflow-test-run-button.tsx
│   ├── instrumentation.ts
│   ├── jest.config.ts
│   ├── jest.setup.ts
│   ├── middleware.ts
│   ├── next-env.d.ts
│   ├── next.config.js
│   ├── next_build.sh
│   ├── next_start.sh
│   ├── package.json
│   ├── postcss.config.js
│   ├── proxyFetch.node.ts
│   ├── proxyFetch.ts
│   ├── scripts/
│   │   ├── build-monaco-workers-turbopack.js
│   │   ├── generate-workflow-yaml-json-schema.ts
│   │   └── validate-workflow-examples.ts
│   ├── sentry.client.config.ts
│   ├── sentry.edge.config.ts
│   ├── sentry.server.config.ts
│   ├── shared/
│   │   ├── api/
│   │   │   ├── ApiClient.ts
│   │   │   ├── KeepApiError.ts
│   │   │   ├── __tests__/
│   │   │   │   └── ApiClient.test.ts
│   │   │   ├── enrichment-events.ts
│   │   │   ├── index.ts
│   │   │   ├── providers.ts
│   │   │   ├── server/
│   │   │   │   ├── createServerApiClient.ts
│   │   │   │   └── index.ts
│   │   │   ├── workflow-executions.ts
│   │   │   └── workflows.ts
│   │   ├── constants.ts
│   │   ├── lib/
│   │   │   ├── __tests__/
│   │   │   │   ├── getIconForStatusString.test.tsx
│   │   │   │   ├── logs-utils.test.ts
│   │   │   │   ├── oauth2proxy-auth.test.ts
│   │   │   │   ├── object-utils.test.ts
│   │   │   │   ├── provider-utils.test.ts
│   │   │   │   ├── regex-utils.test.ts
│   │   │   │   ├── severity-utils.test.ts
│   │   │   │   └── status-utils.test.ts
│   │   │   ├── capture.ts
│   │   │   ├── downloadFileFromString.ts
│   │   │   ├── encodings.ts
│   │   │   ├── getApiUrlFromConfig.ts
│   │   │   ├── hooks/
│   │   │   │   ├── __tests__/
│   │   │   │   │   └── useSignOut.test.ts
│   │   │   │   ├── useApi.tsx
│   │   │   │   ├── useHealth.ts
│   │   │   │   ├── useHydratedSession.tsx
│   │   │   │   ├── useMounted.tsx
│   │   │   │   ├── useSetSentryUser.ts
│   │   │   │   └── useSignOut.ts
│   │   │   ├── logs-utils.ts
│   │   │   ├── oauth2proxy-auth.ts
│   │   │   ├── object-utils.ts
│   │   │   ├── provider-utils.ts
│   │   │   ├── regex-utils.ts
│   │   │   ├── server/
│   │   │   │   └── getConfig.ts
│   │   │   ├── state-utils.ts
│   │   │   ├── status-utils.ts
│   │   │   └── tremor-utils.ts
│   │   ├── tests/
│   │   │   └── next-auth-mock.tsx
│   │   └── ui/
│   │       ├── DateTimeField.tsx
│   │       ├── DebugJSON/
│   │       │   ├── DebugJSON.tsx
│   │       │   └── index.ts
│   │       ├── Drawer/
│   │       │   ├── Drawer.tsx
│   │       │   ├── TremorDrawer.tsx
│   │       │   └── index.ts
│   │       ├── DropdownMenu/
│   │       │   ├── DropdownMenu.css
│   │       │   ├── DropdownMenu.tsx
│   │       │   └── index.ts
│   │       ├── EmptyState/
│   │       │   ├── EmptyStateCard.tsx
│   │       │   └── index.ts
│   │       ├── ErrorComponent/
│   │       │   ├── ErrorComponent.tsx
│   │       │   └── index.ts
│   │       ├── FieldHeader.tsx
│   │       ├── FormattedContent/
│   │       │   └── FormattedContent.tsx
│   │       ├── Input/
│   │       │   └── index.tsx
│   │       ├── JsonCard/
│   │       │   ├── JsonCard.tsx
│   │       │   └── index.ts
│   │       ├── KeepLoader/
│   │       │   └── KeepLoader.tsx
│   │       ├── KeepLogoError/
│   │       │   ├── KeepLogoError.tsx
│   │       │   ├── index.ts
│   │       │   └── logo-error.css
│   │       ├── MarkdownHTML/
│   │       │   ├── MarkdownHTML.tsx
│   │       │   └── index.ts
│   │       ├── MonacoCELEditor/
│   │       │   ├── MonacoCel.tsx
│   │       │   ├── MonacoCel.turbopack.tsx
│   │       │   ├── cel-support.ts
│   │       │   ├── editor.scss
│   │       │   ├── handle-completions.ts
│   │       │   ├── index.ts
│   │       │   ├── monaco-cel-editor.tsx
│   │       │   └── validation-hook.ts
│   │       ├── MonacoEditor/
│   │       │   ├── MonacoEditorCDN.tsx
│   │       │   ├── MonacoEditorNPM.tsx
│   │       │   ├── index.ts
│   │       │   └── index.turbopack.ts
│   │       ├── MonacoYAMLEditor/
│   │       │   ├── MonacoYAMLEditor.types.ts
│   │       │   ├── editor.client.tsx
│   │       │   ├── editor.client.turbopack.tsx
│   │       │   ├── index.ts
│   │       │   └── index.turbopack.ts
│   │       ├── PageSubtitle.tsx
│   │       ├── PageTitle.tsx
│   │       ├── PostHogPageView.tsx
│   │       ├── ResizableColumns/
│   │       │   ├── index.ts
│   │       │   └── ui/
│   │       │       └── ResizableColumns.tsx
│   │       ├── Select/
│   │       │   ├── Select.tsx
│   │       │   └── index.ts
│   │       ├── SeverityBorderIcon/
│   │       │   ├── SeverityBorderIcon.tsx
│   │       │   └── index.ts
│   │       ├── SeverityLabel/
│   │       │   ├── SeverityLabel.tsx
│   │       │   └── index.ts
│   │       ├── TabLinkNavigation/
│   │       │   ├── TabLinkNavigation.tsx
│   │       │   ├── TabNavigationLink.tsx
│   │       │   └── index.tsx
│   │       ├── TableIndeterminateCheckbox/
│   │       │   ├── TableIndeterminateCheckbox.tsx
│   │       │   └── index.ts
│   │       ├── TablePagination/
│   │       │   ├── TablePagination.tsx
│   │       │   └── index.ts
│   │       ├── TableSeverityCell/
│   │       │   ├── TableSeverityCell.tsx
│   │       │   └── index.ts
│   │       ├── Tooltip/
│   │       │   ├── Tooltip.tsx
│   │       │   └── index.ts
│   │       ├── TraceViewer/
│   │       │   ├── Trace.ts
│   │       │   ├── TraceViewer.tsx
│   │       │   └── index.ts
│   │       ├── VerticalRoundedList/
│   │       │   ├── VerticalRoundedList.tsx
│   │       │   ├── index.ts
│   │       │   └── vertical-rounded-list.css
│   │       ├── WorkflowYAMLEditor/
│   │       │   ├── index.ts
│   │       │   ├── lib/
│   │       │   │   ├── useYamlValidation.ts
│   │       │   │   └── utils.ts
│   │       │   ├── model/
│   │       │   │   └── types.ts
│   │       │   └── ui/
│   │       │       ├── WorkflowYAMLEditor.tsx
│   │       │       ├── WorkflowYAMLEditorStandalone.tsx
│   │       │       ├── WorkflowYAMLEditorToolbar.tsx
│   │       │       ├── WorkflowYAMLValidationErrors.tsx
│   │       │       └── WorkflowYamlEditorHeader.tsx
│   │       ├── WorkflowYAMLEditorWithLogs/
│   │       │   ├── WorkflowYAMLEditorWithLogs.css
│   │       │   ├── WorkflowYAMLEditorWithLogs.tsx
│   │       │   └── index.tsx
│   │       ├── index.ts
│   │       ├── theme/
│   │       │   ├── ThemeControl.tsx
│   │       │   ├── ThemeScript.tsx
│   │       │   ├── WatchUpdateTheme.ts
│   │       │   └── index.ts
│   │       └── utils/
│   │           ├── favicon.ts
│   │           ├── getIconForStatusString.tsx
│   │           ├── severity-utils.ts
│   │           ├── showErrorToast.tsx
│   │           ├── showSuccessToast.tsx
│   │           └── table-utils.ts
│   ├── styles/
│   │   └── linear.scss
│   ├── tailwind.config.js
│   ├── tsconfig.json
│   ├── tsconfig.scripts.json
│   ├── types/
│   │   ├── auth.d.ts
│   │   ├── internal-config.ts
│   │   └── react-table.d.ts
│   ├── utils/
│   │   ├── apiUrl.ts
│   │   ├── authenticationType.ts
│   │   ├── cel-ast.ts
│   │   ├── fatigue.ts
│   │   ├── helpers.ts
│   │   ├── hooks/
│   │   │   ├── useAI.ts
│   │   │   ├── useAlertPolling.ts
│   │   │   ├── useAlertQuality.ts
│   │   │   ├── useConfig.ts
│   │   │   ├── useDashboardMetricWidgets.ts
│   │   │   ├── useDashboardPresets.ts
│   │   │   ├── useDashboards.ts
│   │   │   ├── useDebouncedValue.ts
│   │   │   ├── useDeduplicationRules.ts
│   │   │   ├── useEnrichmentEvents.ts
│   │   │   ├── useExpandedRows.ts
│   │   │   ├── useExtractionRules.ts
│   │   │   ├── useGroupExpansion.ts
│   │   │   ├── useGroups.ts
│   │   │   ├── useIncidents.ts
│   │   │   ├── useLocalStorage.ts
│   │   │   ├── useMaintenanceRules.ts
│   │   │   ├── useMappingRules.ts
│   │   │   ├── usePermissions.ts
│   │   │   ├── useProviderLogs.ts
│   │   │   ├── useProviders.ts
│   │   │   ├── usePusher.ts
│   │   │   ├── useRoles.ts
│   │   │   ├── useRules.ts
│   │   │   ├── useScopes.ts
│   │   │   ├── useSearchAlerts.ts
│   │   │   ├── useTags.ts
│   │   │   ├── useTenantConfiguration.ts
│   │   │   └── useWorkflowSecrets.ts
│   │   ├── reactFlow.ts
│   │   └── type-utils.ts
│   └── widgets/
│       ├── alerts-table/
│       │   ├── lib/
│       │   │   ├── alert-table-list-format.tsx
│       │   │   ├── alert-table-time-format.tsx
│       │   │   └── alert-table-utils.tsx
│       │   └── ui/
│       │       ├── ActionTraySelection.tsx
│       │       ├── ColumnSelection.tsx
│       │       ├── RowStyleSelection.tsx
│       │       ├── SettingsSelection.tsx
│       │       ├── TitleAndFilters.tsx
│       │       ├── __tests__/
│       │       │   ├── alert-assignee.test.tsx
│       │       │   ├── alert-grouped-row.test.tsx
│       │       │   └── useAlertsTableData.test.ts
│       │       ├── alert-actions.tsx
│       │       ├── alert-assignee.tsx
│       │       ├── alert-extra-payload.tsx
│       │       ├── alert-grouped-row.tsx
│       │       ├── alert-pagination.tsx
│       │       ├── alert-table-column-rename.tsx
│       │       ├── alert-table-headers.tsx
│       │       ├── alert-table-server-side.tsx
│       │       ├── alert-table.tsx
│       │       ├── alerts-table-body.tsx
│       │       └── useAlertsTableData.ts
│       └── workflow-builder/
│           ├── __tests__/
│           │   ├── workflow-builder-widget.test.tsx
│           │   └── workflow-builder.test.tsx
│           ├── empty-builder-state.tsx
│           ├── index.ts
│           ├── workflow-builder-card.tsx
│           ├── workflow-builder-widget-safe.tsx
│           ├── workflow-builder-widget.tsx
│           └── workflow-builder.tsx
├── keycloak/
│   ├── Dockerfile.keycloak
│   ├── KEYCLOAK_LDAP.md
│   ├── docker-compose.yaml
│   ├── event_listeners/
│   │   └── last-login-event-listener-0.0.1-SNAPSHOT.jar
│   ├── generate_ldap.py
│   ├── javascript_providers/
│   │   ├── keep-abac-policy/
│   │   │   ├── META-INF/
│   │   │   │   └── keycloak-scripts.json
│   │   │   └── keep-abac-policy.js
│   │   └── keep-abac-policy.jar
│   ├── jsons/
│   │   ├── group-claim.json
│   │   ├── group-mapper.json
│   │   └── tenant-ids-js-mapper.json
│   ├── keep-realm.json
│   ├── keycloak_entrypoint.sh
│   ├── ldap.ldif
│   ├── ldap_generated.ldif
│   ├── ldif/
│   │   ├── ldap_orgs.ldif
│   │   └── ldap_orgs_new.ldif
│   ├── readme.md
│   └── themes/
│       └── keep.jar
├── oauth2proxy/
│   ├── docker-compose-oauth2proxy.yml
│   └── nginx.conf
├── otel-shared/
│   ├── alertmanager.yml
│   ├── grafana-datasources.yaml
│   ├── otel-collector-config.yaml
│   ├── prometheus.yaml
│   ├── tempo.yaml
│   └── vector.toml
├── prometheus/
│   └── prometheus.yml
├── proxy/
│   ├── README.md
│   ├── docker-compose-proxy.yml
│   ├── nginx.conf
│   └── squid.conf
├── pyproject.toml
├── render.yaml
├── scripts/
│   ├── docs_generate_api_docs_from_openapi.sh
│   ├── docs_get_providers_list.py
│   ├── docs_openapi_converter.py
│   ├── docs_render_provider_snippets.py
│   ├── docs_validate_navigation.sh
│   ├── docs_validate_openapi_is_actual.sh
│   ├── migrate_to_elastic.py
│   ├── save_providers_list.py
│   ├── shoot_alerts_from_dump.py
│   ├── simulate_alerts.py
│   ├── simulate_alerts.sh
│   ├── simulate_rules.py
│   └── workflow_yaml_generate_json_schema.sh
├── start.sh
├── templates/
│   └── CHANGELOG.md
└── tests/
    ├── Dockerfile.keycloak.test
    ├── __init__.py
    ├── cel_to_sql/
    │   ├── cel-to-sql-test-cases.json
    │   ├── order-by-exp-test-cases.json
    │   ├── test_cel_to_ast.py
    │   ├── test_cel_to_sql.py
    │   └── test_order_by_exp.py
    ├── conftest.py
    ├── deduplication/
    │   ├── test_deduplications.py
    │   └── test_deduplications_provisioning.py
    ├── docker-compose-elastic.yml
    ├── docker-compose-keycloak.yml
    ├── docker-compose-mysql.yml
    ├── e2e_tests/
    │   ├── docker-compose-e2e-mysql.yml
    │   ├── docker-compose-e2e-postgres.yml
    │   ├── docker-compose-e2e-redis-sentinel-noauth.yml
    │   ├── docker-compose-e2e-redis.yml
    │   ├── docker-compose-e2e-sqlite.yml
    │   ├── docker-entrypoint-initdb.d/
    │   │   └── update-postgresql-conf.sh
    │   ├── grafana.ini
    │   ├── incidents_alerts_tests/
    │   │   ├── incidents_alerts_setup.py
    │   │   ├── test_filtering_sort_search_on_alerts.py
    │   │   ├── test_filtering_sort_search_on_incidents.py
    │   │   ├── test_mentions_in_incident_comments.py
    │   │   └── test_xss_protection.py
    │   ├── postgres-custom.conf
    │   ├── test_end_to_end.py
    │   ├── test_end_to_end_db_auth.py
    │   ├── test_end_to_end_theme.py
    │   ├── test_grafana_provider.py
    │   ├── test_pushing_prometheus_alerts.py
    │   ├── test_pushing_prometheus_config.yaml
    │   ├── test_pushing_prometheus_rules.yaml
    │   ├── test_redis_sentinel_e2e_full.py
    │   ├── test_topology.py
    │   ├── utils.py
    │   ├── workflow-alert-log.yaml
    │   ├── workflow-incident-log.yaml
    │   ├── workflow-inputs-alert.yaml
    │   ├── workflow-inputs.yaml
    │   ├── workflow-interval.yaml
    │   ├── workflow-invalid-sample.yaml
    │   ├── workflow-quotes-sample.yaml
    │   ├── workflow-sample-npm.yaml
    │   ├── workflow-sample.yaml
    │   └── workflow-valid-sample.yaml
    ├── fixtures/
    │   ├── __init__.py
    │   ├── client.py
    │   └── workflow_manager.py
    ├── keycloak-test-realm-export.json
    ├── providers/
    │   └── jira_provider/
    │       └── test_jira_priority_fix.py
    ├── provision/
    │   ├── workflows_1/
    │   │   ├── provision_example_1.yml
    │   │   ├── provision_example_2.yml
    │   │   └── provision_example_3.yml
    │   ├── workflows_2/
    │   │   ├── provision_example_1.yml
    │   │   └── provision_example_2.yml
    │   ├── workflows_3/
    │   │   └── workflows_with_no_name.yml
    │   └── workflows_4/
    │       └── console_example.yml
    ├── test.json
    ├── test_actions.py
    ├── test_alert_dto.py
    ├── test_alert_evaluation.py
    ├── test_alert_tenrary.py
    ├── test_alert_utils.py
    ├── test_auth.py
    ├── test_auth_new.py
    ├── test_auto_resolve_workflow.py
    ├── test_batch_enrich_cel.py
    ├── test_conditions.py
    ├── test_contextmanager.py
    ├── test_counting.py
    ├── test_counting_integration.py
    ├── test_cyaml.py
    ├── test_dismissal_expiry_bug.py
    ├── test_enrichments.py
    ├── test_extraction_rules.py
    ├── test_functions.py
    ├── test_incidents.py
    ├── test_iohandler.py
    ├── test_jira_provider.py
    ├── test_keep_provider_time_delta.py
    ├── test_maintenance_windows_bl.py
    ├── test_metrics.py
    ├── test_pagerduty_provider.py
    ├── test_parser.py
    ├── test_provider_factory.py
    ├── test_provider_reprovisioning.py
    ├── test_provider_validation_fields.py
    ├── test_providers_api.py
    ├── test_providers_yaml_provisioning.py
    ├── test_provisioning.py
    ├── test_rules_api.py
    ├── test_rules_engine.py
    ├── test_search_alerts.py
    ├── test_search_alerts_configuration.py
    ├── test_secretmanager.py
    ├── test_servicenow_provider.py
    ├── test_settings_api.py
    ├── test_smtp_provider.py
    ├── test_steps.py
    ├── test_teams_provider.py
    ├── test_topology.py
    ├── test_workflow_api.py
    ├── test_workflow_cel_filter.py
    ├── test_workflow_execution.py
    ├── test_workflow_filters.py
    ├── test_workflow_severity_comparisons.py
    ├── test_workflowmanager.py
    ├── test_workflows.py
    ├── test_workflows_update.py
    ├── test_workflowstore.py
    └── workflows/
        ├── db_disk_space_for_testing.yml
        ├── providers_for_testing.yaml
        ├── reusable_actions_for_testing.yml
        ├── reusable_alert_for_testing.yml
        └── reusable_alert_with_actions_for_testing.yml
Download .txt
Showing preview only (526K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (5841 symbols across 1071 files)

FILE: ee/identitymanager/identity_managers/auth0/auth0_authverifier.py
  function _discover_jwks_uri (line 15) | def _discover_jwks_uri(auth_domain: str) -> str:
  class Auth0AuthVerifier (line 60) | class Auth0AuthVerifier(AuthVerifierBase):
    method __init__ (line 63) | def __init__(self, scopes: list[str] = []) -> None:
    method _verify_bearer_token (line 77) | def _verify_bearer_token(self, token) -> AuthenticatedEntity:

FILE: ee/identitymanager/identity_managers/auth0/auth0_identitymanager.py
  class Auth0IdentityManager (line 17) | class Auth0IdentityManager(BaseIdentityManager):
    method __init__ (line 18) | def __init__(self, tenant_id, context_manager: ContextManager, **kwargs):
    method get_users (line 31) | def get_users(self) -> list[User]:
    method _get_users_auth0 (line 34) | def _get_users_auth0(self, tenant_id: str) -> list[User]:
    method create_user (line 53) | def create_user(self, user_email: str, role: str, **kwargs) -> dict:
    method delete_user (line 56) | def delete_user(self, user_email: str) -> dict:
    method get_auth_verifier (line 65) | def get_auth_verifier(self, scopes) -> Auth0AuthVerifier:
    method _create_user_auth0 (line 68) | def _create_user_auth0(self, user_email: str, tenant_id: str, role: st...
    method update_user (line 94) | def update_user(self, user_email: str, update_data: dict) -> User:

FILE: ee/identitymanager/identity_managers/auth0/auth0_utils.py
  function getAuth0Client (line 7) | def getAuth0Client() -> Auth0:

FILE: ee/identitymanager/identity_managers/azuread/azuread_authverifier.py
  class AzureADGroupMapper (line 29) | class AzureADGroupMapper:
    method __init__ (line 32) | def __init__(self):
    method get_role_from_groups (line 48) | def get_role_from_groups(self, groups: List[str]) -> Optional[str]:
  class AzureADKeysManager (line 68) | class AzureADKeysManager:
    method __new__ (line 76) | def __new__(cls):
    method __init__ (line 81) | def __init__(self):
    method _refresh_keys (line 89) | def _refresh_keys(self) -> None:
    method get_signing_key (line 118) | def get_signing_key(self, kid: str) -> Optional[Any]:
  class AzureadAuthVerifier (line 137) | class AzureadAuthVerifier(AuthVerifierBase):
    method __init__ (line 140) | def __init__(self, scopes: list[str] = []) -> None:
    method _verify_bearer_token (line 155) | def _verify_bearer_token(
    method _authorize (line 322) | def _authorize(self, authenticated_entity: AuthenticatedEntity) -> None:

FILE: ee/identitymanager/identity_managers/azuread/azuread_identitymanager.py
  class AzureadIdentityManager (line 12) | class AzureadIdentityManager(BaseIdentityManager):
    method __init__ (line 13) | def __init__(self, tenant_id, context_manager: ContextManager, **kwargs):
    method get_users (line 19) | def get_users(self) -> list[User]:
    method create_user (line 23) | def create_user(self, user_email: str, role: str, **kwargs) -> dict:
    method delete_user (line 26) | def delete_user(self, user_email: str) -> dict:
    method get_auth_verifier (line 29) | def get_auth_verifier(self, scopes) -> AzureadAuthVerifier:
    method update_user (line 32) | def update_user(self, user_email: str, update_data: dict) -> User:

FILE: ee/identitymanager/identity_managers/keycloak/keycloak_authverifier.py
  function patched_init (line 25) | def patched_init(
  class KeycloakAuthVerifier (line 48) | class KeycloakAuthVerifier(AuthVerifierBase):
    method __init__ (line 51) | def __init__(self, scopes: list[str] = []) -> None:
    method tenants (line 114) | def tenants(self):
    method _reload_tenants (line 132) | def _reload_tenants(self):
    method get_org_name_by_tenant_id (line 139) | def get_org_name_by_tenant_id(self, tenant_id):
    method _check_if_group_represents_org (line 147) | def _check_if_group_represents_org(self, group_name: str):
    method _get_org_name (line 171) | def _get_org_name(self, group_name):
    method _get_role_in_org (line 183) | def _get_role_in_org(self, user_groups, org_name):
    method _verify_bearer_token (line 194) | def _verify_bearer_token(
    method _authorize (line 343) | def _authorize(self, authenticated_entity: AuthenticatedEntity) -> None:
    method authorize_resource (line 373) | def authorize_resource(

FILE: ee/identitymanager/identity_managers/keycloak/keycloak_identitymanager.py
  class KeycloakIdentityManager (line 30) | class KeycloakIdentityManager(BaseIdentityManager):
    method __init__ (line 46) | def __init__(self, tenant_id, context_manager: ContextManager, **kwargs):
    method on_start (line 95) | def on_start(self, app) -> None:
    method _scope_name_to_id (line 190) | def _scope_name_to_id(self, all_scopes, scope_name: str) -> str:
    method get_permission_by_name (line 214) | def get_permission_by_name(self, permission_name):
    method create_scope_based_permission (line 226) | def create_scope_based_permission(self, role: Role, policy_id: str) ->...
    method create_scope (line 282) | def create_scope(self, scope: str) -> None:
    method create_role (line 295) | def create_role(self, role: Role, predefined=False) -> str:
    method update_role (line 324) | def update_role(self, role_id: str, role: Role) -> str:
    method create_role_policy (line 354) | def create_role_policy(self, role_id: str, role_name: str, role_descri...
    method support_sso (line 394) | def support_sso(self) -> bool:
    method get_sso_providers (line 397) | def get_sso_providers(self) -> list[str]:
    method get_sso_wizard_url (line 400) | def get_sso_wizard_url(self, authenticated_entity: AuthenticatedEntity...
    method get_users (line 405) | def get_users(self) -> list[User]:
    method create_user (line 442) | def create_user(
    method get_user_id_by_email (line 492) | def get_user_id_by_email(self, user_email: str) -> str:
    method get_user_current_role (line 505) | def get_user_current_role(self, user_id: str) -> str:
    method add_user_to_group (line 529) | def add_user_to_group(self, user_id: str, group: str):
    method update_user (line 536) | def update_user(self, user_email: str, update_data: dict) -> dict:
    method delete_user (line 591) | def delete_user(self, user_email: str) -> dict:
    method get_auth_verifier (line 601) | def get_auth_verifier(self, scopes: list) -> AuthVerifierBase:
    method create_resource (line 604) | def create_resource(
    method delete_resource (line 628) | def delete_resource(self, resource_id: str) -> None:
    method get_groups (line 642) | def get_groups(self) -> list[dict]:
    method create_user_policy (line 672) | def create_user_policy(self, perm, permission: ResourcePermission) -> ...
    method create_group_policy (line 711) | def create_group_policy(self, perm, permission: ResourcePermission) ->...
    method create_permissions (line 749) | def create_permissions(self, permissions: list[ResourcePermission]) ->...
    method get_permissions (line 864) | def get_permissions(self) -> list[ResourcePermission]:
    method get_user_permission_on_resource_type (line 933) | def get_user_permission_on_resource_type(
    method get_policies (line 992) | def get_policies(self) -> list[dict]:
    method get_roles (line 1002) | def get_roles(self) -> list[Role]:
    method get_role_by_role_name (line 1062) | def get_role_by_role_name(self, role_name: str) -> Role:
    method delete_role (line 1070) | def delete_role(self, role_id: str) -> None:
    method create_group (line 1098) | def create_group(
    method update_group (line 1128) | def update_group(
    method delete_group (line 1189) | def delete_group(self, group_name: str) -> None:

FILE: keep-ui/app/(health)/health/check.tsx
  function ProviderHealthPage (line 46) | function ProviderHealthPage() {

FILE: keep-ui/app/(health)/health/modal.tsx
  type ProviderHealthResultsModalProps (line 14) | interface ProviderHealthResultsModalProps {

FILE: keep-ui/app/(health)/layout.tsx
  type RootLayoutProps (line 21) | type RootLayoutProps = {
  function RootLayout (line 25) | async function RootLayout({ children }: RootLayoutProps) {

FILE: keep-ui/app/(keep)/[...not-found]/page.tsx
  function NotFoundDummy (line 6) | function NotFoundDummy() {

FILE: keep-ui/app/(keep)/ai/ai-plugins.tsx
  function RangeInputWithLabel (line 17) | function RangeInputWithLabel({
  function AIPlugins (line 62) | function AIPlugins() {

FILE: keep-ui/app/(keep)/ai/model.ts
  type FloatOrIntSetting (line 1) | interface FloatOrIntSetting {
  type BoolSetting (line 8) | interface BoolSetting {
  type BaseSetting (line 13) | interface BaseSetting {
  type AlgorithmSetting (line 18) | type AlgorithmSetting = BaseSetting & (FloatOrIntSetting | BoolSetting);
  type Algorithm (line 20) | interface Algorithm {
  type AIConfig (line 26) | interface AIConfig {
  type AIStats (line 36) | interface AIStats {
  type AILogs (line 43) | interface AILogs {

FILE: keep-ui/app/(keep)/ai/page.tsx
  function Page (line 3) | function Page() {

FILE: keep-ui/app/(keep)/alerts/[id]/page.tsx
  type PageProps (line 5) | type PageProps = {
  function Page (line 10) | async function Page(props: PageProps) {

FILE: keep-ui/app/(keep)/alerts/[id]/ui/alert-table-facet-dynamic.tsx
  type AddFacetModalProps (line 11) | interface AddFacetModalProps {
  type DynamicFacetProps (line 74) | interface DynamicFacetProps extends FacetProps {

FILE: keep-ui/app/(keep)/alerts/[id]/ui/alert-table-facet-types.tsx
  type DynamicFacet (line 4) | interface DynamicFacet {
  type FacetValue (line 9) | interface FacetValue {
  type FacetFilters (line 15) | interface FacetFilters {
  type FacetValueProps (line 19) | interface FacetValueProps {
  type FacetProps (line 29) | interface FacetProps {
  type AlertFacetsProps (line 39) | interface AlertFacetsProps {

FILE: keep-ui/app/(keep)/alerts/[id]/ui/alert-table-tab-panel-server-side.tsx
  type Props (line 13) | interface Props {
  function AlertTableTabPanelServerSide (line 31) | function AlertTableTabPanelServerSide({

FILE: keep-ui/app/(keep)/alerts/[id]/ui/alerts.tsx
  type AlertsProps (line 41) | type AlertsProps = {
  function Alerts (line 46) | function Alerts({ presetName, initialFacets }: AlertsProps) {

FILE: keep-ui/app/(keep)/dashboard/GridItem.tsx
  type GridItemProps (line 9) | interface GridItemProps {

FILE: keep-ui/app/(keep)/dashboard/GridItemContainer.tsx
  type GridItemContainerProps (line 5) | interface GridItemContainerProps {

FILE: keep-ui/app/(keep)/dashboard/GridLayout.tsx
  type GridLayoutProps (line 11) | interface GridLayoutProps {

FILE: keep-ui/app/(keep)/dashboard/MenuButton.tsx
  type MenuButtonProps (line 8) | interface MenuButtonProps {

FILE: keep-ui/app/(keep)/dashboard/WidgetModal.tsx
  type WidgetForm (line 12) | interface WidgetForm {
  type WidgetModalProps (line 17) | interface WidgetModalProps {

FILE: keep-ui/app/(keep)/dashboard/[id]/dashboard.tsx
  constant DASHBOARD_FILTERS (line 28) | const DASHBOARD_FILTERS = [

FILE: keep-ui/app/(keep)/dashboard/[id]/page.tsx
  function Page (line 3) | function Page() {

FILE: keep-ui/app/(keep)/dashboard/alert-quality-table.tsx
  constant ALERT_QUALITY_FILTERS (line 27) | const ALERT_QUALITY_FILTERS = [
  type AlertMetricQuality (line 63) | interface AlertMetricQuality {
  type FinalAlertQuality (line 70) | type FinalAlertQuality = Provider &
  type Pagination (line 72) | interface Pagination {
  function toArray (line 125) | function toArray(value: string | string[]) {
  function getProviderDisplayName (line 236) | function getProviderDisplayName(provider: Provider) {

FILE: keep-ui/app/(keep)/dashboard/types.tsx
  type LayoutItem (line 4) | interface LayoutItem {
  type GenericsMetrics (line 15) | interface GenericsMetrics {
  type WidgetType (line 26) | enum WidgetType {
  type PresetPanelType (line 32) | enum PresetPanelType {
  type WidgetData (line 37) | interface WidgetData extends LayoutItem {
  type Threshold (line 49) | interface Threshold {

FILE: keep-ui/app/(keep)/dashboard/widget-types/generic-metrics/generic-metrics-grid-item.tsx
  type GridItemProps (line 5) | interface GridItemProps {
  function renderGenericMetrics (line 36) | function renderGenericMetrics() {

FILE: keep-ui/app/(keep)/dashboard/widget-types/generic-metrics/generic-metrics-widget-form.tsx
  constant GENERIC_METRICS (line 6) | const GENERIC_METRICS = [
  type GenericMetricsForm (line 17) | interface GenericMetricsForm {
  type GenericMetricsWidgetFormProps (line 21) | interface GenericMetricsWidgetFormProps {
  function getLayoutValues (line 46) | function getLayoutValues(): LayoutItem {

FILE: keep-ui/app/(keep)/dashboard/widget-types/metric/metric-grid-item.tsx
  type GridItemProps (line 5) | interface GridItemProps {

FILE: keep-ui/app/(keep)/dashboard/widget-types/metric/metric-widget-form.tsx
  type PresetForm (line 7) | interface PresetForm {
  type MetricWidgetFormProps (line 11) | interface MetricWidgetFormProps {
  function getLayoutValues (line 39) | function getLayoutValues(): LayoutItem {

FILE: keep-ui/app/(keep)/dashboard/widget-types/preset/columns-selection.tsx
  type ColumnsSelectionProps (line 6) | interface ColumnsSelectionProps {

FILE: keep-ui/app/(keep)/dashboard/widget-types/preset/preset-grid-item.tsx
  type GridItemProps (line 17) | interface GridItemProps {
  function handleGoToPresetClick (line 59) | function handleGoToPresetClick() {
  function hexToRgb (line 81) | function hexToRgb(hex: string, alpha: number = 1) {
  function renderCEL (line 101) | function renderCEL() {
  function renderAlertsCountText (line 128) | function renderAlertsCountText() {

FILE: keep-ui/app/(keep)/dashboard/widget-types/preset/preset-widget-form.tsx
  type PresetForm (line 23) | interface PresetForm {
  type PresetWidgetFormProps (line 32) | interface PresetWidgetFormProps {
  function getLayoutValues (line 88) | function getLayoutValues(): LayoutItem {

FILE: keep-ui/app/(keep)/dashboard/widget-types/preset/widget-alert-count-panel.tsx
  type WidgetAlertCountPanelProps (line 12) | interface WidgetAlertCountPanelProps {
  function handleGoToPresetClick (line 81) | function handleGoToPresetClick() {
  function handleCustomLinkClick (line 85) | function handleCustomLinkClick() {
  function hexToRgb (line 104) | function hexToRgb(hex: string, alpha: number = 1) {

FILE: keep-ui/app/(keep)/dashboard/widget-types/preset/widget-alerts-table.tsx
  type WidgetAlertsTableProps (line 25) | interface WidgetAlertsTableProps {
  function renderHeaders (line 129) | function renderHeaders() {
  function renderTableBody (line 154) | function renderTableBody() {

FILE: keep-ui/app/(keep)/deduplication/DeduplicationSidebar.tsx
  type ProviderOption (line 30) | interface ProviderOption {
  type DeduplicationSidebarProps (line 36) | interface DeduplicationSidebarProps {

FILE: keep-ui/app/(keep)/deduplication/DeduplicationTable.tsx
  type DeduplicationTableProps (line 40) | type DeduplicationTableProps = {
  function resolveDeleteButtonTooltip (line 124) | function resolveDeleteButtonTooltip(

FILE: keep-ui/app/(keep)/deduplication/models.tsx
  type DeduplicationRule (line 1) | interface DeduplicationRule {

FILE: keep-ui/app/(keep)/deduplication/page.tsx
  function Page (line 3) | function Page() {

FILE: keep-ui/app/(keep)/extraction/[rule_id]/executions/[execution_id]/page.tsx
  function ExtractionExecutionDetailsPage (line 13) | function ExtractionExecutionDetailsPage(props: {

FILE: keep-ui/app/(keep)/extraction/[rule_id]/executions/page.tsx
  type Pagination (line 11) | interface Pagination {
  function ExtractionExecutionsPage (line 16) | function ExtractionExecutionsPage(props: {

FILE: keep-ui/app/(keep)/extraction/create-or-update-extraction-rule.tsx
  type Props (line 26) | interface Props {
  function CreateOrUpdateExtractionRule (line 31) | function CreateOrUpdateExtractionRule({

FILE: keep-ui/app/(keep)/extraction/extraction.tsx
  function Extraction (line 19) | function Extraction() {

FILE: keep-ui/app/(keep)/extraction/extractions-table.tsx
  type Props (line 37) | interface Props {
  function ExtractionsTable (line 42) | function ExtractionsTable({ extractions, editCallback }: Props) {

FILE: keep-ui/app/(keep)/extraction/layout.tsx
  function Layout (line 1) | function Layout({ children }: { children: any }) {

FILE: keep-ui/app/(keep)/extraction/model.ts
  type ExtractionRule (line 1) | interface ExtractionRule {

FILE: keep-ui/app/(keep)/extraction/page.tsx
  function Page (line 3) | function Page() {

FILE: keep-ui/app/(keep)/extraction/run-extraction-modal.tsx
  type Props (line 16) | interface Props {
  function RunExtractionModal (line 22) | function RunExtractionModal({ ruleId, isOpen, onClose }: Props) {

FILE: keep-ui/app/(keep)/incidents/[id]/activity/incident-activity.tsx
  type IncidentActivity (line 23) | interface IncidentActivity {
  constant ACTION_TYPES (line 32) | const ACTION_TYPES = [
  function Item (line 45) | function Item({
  function IncidentActivity (line 67) | function IncidentActivity({ incident }: { incident: IncidentDto }) {

FILE: keep-ui/app/(keep)/incidents/[id]/activity/lib/extractTaggedUsers.ts
  function extractTaggedUsers (line 8) | function extractTaggedUsers(content: string): string[] {

FILE: keep-ui/app/(keep)/incidents/[id]/activity/page.tsx
  function IncidentActivityPage (line 7) | async function IncidentActivityPage(props: {
  function generateMetadata (line 22) | async function generateMetadata(props: {

FILE: keep-ui/app/(keep)/incidents/[id]/activity/ui/IncidentActivityComment.tsx
  function IncidentActivityComment (line 16) | function IncidentActivityComment({

FILE: keep-ui/app/(keep)/incidents/[id]/activity/ui/IncidentActivityItem.tsx
  function IncidentActivityItem (line 9) | function IncidentActivityItem({ activity }: { activity: IncidentActivity...

FILE: keep-ui/app/(keep)/incidents/[id]/activity/ui/IncidentCommentInput.tsx
  type IncidentCommentInputProps (line 21) | interface IncidentCommentInputProps {
  function IncidentCommentInput (line 32) | function IncidentCommentInput({

FILE: keep-ui/app/(keep)/incidents/[id]/alerts/incident-alert-action-tray.tsx
  type Props (line 10) | interface Props {
  function IncidentAlertActionTray (line 17) | function IncidentAlertActionTray({

FILE: keep-ui/app/(keep)/incidents/[id]/alerts/incident-alert-actions.tsx
  function IncidentAlertsActions (line 8) | function IncidentAlertsActions({

FILE: keep-ui/app/(keep)/incidents/[id]/alerts/incident-alert-table-body-skeleton.tsx
  function IncidentAlertsTableBodySkeleton (line 10) | function IncidentAlertsTableBodySkeleton({

FILE: keep-ui/app/(keep)/incidents/[id]/alerts/incident-alerts.tsx
  type Props (line 43) | interface Props {
  type Pagination (line 47) | interface Pagination {
  function IncidentAlerts (line 54) | function IncidentAlerts({ incident }: Props) {

FILE: keep-ui/app/(keep)/incidents/[id]/alerts/page.tsx
  type PageProps (line 5) | type PageProps = {
  function IncidentAlertsPage (line 9) | async function IncidentAlertsPage(props: PageProps) {
  function generateMetadata (line 18) | async function generateMetadata(props: PageProps) {

FILE: keep-ui/app/(keep)/incidents/[id]/chat/incident-chat.tsx
  constant INSTRUCTIONS (line 31) | const INSTRUCTIONS = `DO NOT, NO MATTER WHAT, MAKE UP ANY INFORMATION OR...
  function IncidentChat (line 37) | function IncidentChat({

FILE: keep-ui/app/(keep)/incidents/[id]/chat/page.client.tsx
  function IncidentChatClientPage (line 8) | function IncidentChatClientPage({

FILE: keep-ui/app/(keep)/incidents/[id]/create-ticket-modal.tsx
  type CreateTicketModalProps (line 12) | interface CreateTicketModalProps {
  function CreateTicketModal (line 18) | function CreateTicketModal({

FILE: keep-ui/app/(keep)/incidents/[id]/enrichments/EnrichmentEditableField.tsx
  type EnrichmentEditableFieldProps (line 9) | interface EnrichmentEditableFieldProps {

FILE: keep-ui/app/(keep)/incidents/[id]/enrichments/EnrichmentEditableForm.tsx
  type EnrichmentEditableFormProps (line 10) | interface EnrichmentEditableFormProps {

FILE: keep-ui/app/(keep)/incidents/[id]/getIncidentWithErrorHandling.tsx
  function _getIncidentWithErrorHandling (line 15) | async function _getIncidentWithErrorHandling(

FILE: keep-ui/app/(keep)/incidents/[id]/incident-header-skeleton.tsx
  function IncidentHeaderSkeleton (line 8) | function IncidentHeaderSkeleton() {

FILE: keep-ui/app/(keep)/incidents/[id]/incident-header.tsx
  function IncidentHeader (line 24) | function IncidentHeader({

FILE: keep-ui/app/(keep)/incidents/[id]/incident-layout-client.tsx
  function IncidentLayoutClient (line 11) | function IncidentLayoutClient({

FILE: keep-ui/app/(keep)/incidents/[id]/incident-overview.tsx
  constant PROVISIONED_ENRICHMENTS (line 41) | const PROVISIONED_ENRICHMENTS = [
  type Props (line 53) | interface Props {
  function Summary (line 57) | function Summary({
  function MergedCallout (line 162) | function MergedCallout({
  function IncidentOverview (line 197) | function IncidentOverview({ incident: initialIncidentData }: Props) {

FILE: keep-ui/app/(keep)/incidents/[id]/incident-tabs-navigation.tsx
  function IncidentTabsNavigation (line 24) | function IncidentTabsNavigation() {

FILE: keep-ui/app/(keep)/incidents/[id]/layout.tsx
  function Layout (line 6) | async function Layout(

FILE: keep-ui/app/(keep)/incidents/[id]/link-ticket-modal.tsx
  type LinkTicketModalProps (line 15) | interface LinkTicketModalProps {
  function LinkTicketModal (line 22) | function LinkTicketModal({

FILE: keep-ui/app/(keep)/incidents/[id]/not-found.tsx
  function NotFound (line 8) | function NotFound() {

FILE: keep-ui/app/(keep)/incidents/[id]/route.tsx
  function GET (line 4) | async function GET(

FILE: keep-ui/app/(keep)/incidents/[id]/ticketing-incident-options.tsx
  type TicketingIncidentOptionsProps (line 17) | interface TicketingIncidentOptionsProps {
  function TicketingIncidentOptions (line 21) | function TicketingIncidentOptions({

FILE: keep-ui/app/(keep)/incidents/[id]/timeline/incident-timeline.tsx
  type EventDotProps (line 47) | interface EventDotProps {
  type AlertBarProps (line 145) | interface AlertBarProps {
  function IncidentTimeline (line 277) | function IncidentTimeline({

FILE: keep-ui/app/(keep)/incidents/[id]/timeline/page.tsx
  type PageProps (line 5) | type PageProps = {
  function IncidentTimelinePage (line 9) | async function IncidentTimelinePage(props: PageProps) {
  function generateMetadata (line 18) | async function generateMetadata(props: PageProps) {

FILE: keep-ui/app/(keep)/incidents/[id]/topology/page.tsx
  type PageProps (line 8) | type PageProps = {
  function IncidentTopologyPage (line 12) | async function IncidentTopologyPage(props: PageProps) {
  function generateMetadata (line 49) | async function generateMetadata(props: PageProps) {

FILE: keep-ui/app/(keep)/incidents/[id]/workflows/incident-workflow-empty.tsx
  function IncidentWorkflowsEmptyState (line 8) | function IncidentWorkflowsEmptyState({

FILE: keep-ui/app/(keep)/incidents/[id]/workflows/incident-workflow-sidebar.tsx
  type IncidentWorkflowSidebarProps (line 15) | interface IncidentWorkflowSidebarProps {

FILE: keep-ui/app/(keep)/incidents/[id]/workflows/incident-workflow-table.tsx
  type Props (line 37) | interface Props {
  type Pagination (line 41) | interface Pagination {
  function IncidentWorkflowTable (line 48) | function IncidentWorkflowTable({ incident }: Props) {

FILE: keep-ui/app/(keep)/incidents/[id]/workflows/page.tsx
  type PageProps (line 5) | type PageProps = {
  function IncidentWorkflowsPage (line 9) | async function IncidentWorkflowsPage(props: PageProps) {
  function generateMetadata (line 18) | async function generateMetadata(props: PageProps) {

FILE: keep-ui/app/(keep)/incidents/incident-overview-skeleton.tsx
  function IncidentOverviewSkeleton (line 4) | function IncidentOverviewSkeleton() {

FILE: keep-ui/app/(keep)/incidents/layout.tsx
  function Layout (line 4) | function Layout({ children }: { children: any }) {

FILE: keep-ui/app/(keep)/incidents/page.tsx
  function Page (line 6) | async function Page() {

FILE: keep-ui/app/(keep)/incidents/predicted-incidents-table.tsx
  type Props (line 21) | interface Props {
  function PredictedIncidentsTable (line 27) | function PredictedIncidentsTable({

FILE: keep-ui/app/(keep)/layout.tsx
  type RootLayoutProps (line 24) | type RootLayoutProps = {
  function RootLayout (line 28) | async function RootLayout({ children }: RootLayoutProps) {

FILE: keep-ui/app/(keep)/maintenance/create-or-update-maintenance-rule.tsx
  type Props (line 28) | interface Props {
  constant DEFAULT_IGNORE_STATUSES (line 33) | const DEFAULT_IGNORE_STATUSES = [
  function CreateOrUpdateMaintenanceRule (line 38) | function CreateOrUpdateMaintenanceRule({

FILE: keep-ui/app/(keep)/maintenance/layout.tsx
  function Layout (line 2) | function Layout({ children }: { children: any }) {

FILE: keep-ui/app/(keep)/maintenance/maintenance-rules-table.tsx
  type Props (line 30) | interface Props {
  function MaintenanceRulesTable (line 35) | function MaintenanceRulesTable({

FILE: keep-ui/app/(keep)/maintenance/maintenance.tsx
  function Maintenance (line 14) | function Maintenance() {

FILE: keep-ui/app/(keep)/maintenance/model.ts
  type MaintenanceRule (line 1) | interface MaintenanceRule {
  type MaintenanceRuleCreate (line 16) | interface MaintenanceRuleCreate {

FILE: keep-ui/app/(keep)/maintenance/page.tsx
  function Page (line 3) | function Page() {

FILE: keep-ui/app/(keep)/mapping/[rule_id]/executions/[execution_id]/page.tsx
  function MappingExecutionDetailsPage (line 13) | function MappingExecutionDetailsPage(props: {

FILE: keep-ui/app/(keep)/mapping/[rule_id]/executions/page.tsx
  type Pagination (line 28) | interface Pagination {
  function MappingExecutionsPage (line 33) | function MappingExecutionsPage(props: {

FILE: keep-ui/app/(keep)/mapping/create-or-edit-mapping.tsx
  type Props (line 42) | interface Props {
  function CreateOrEditMapping (line 47) | function CreateOrEditMapping({

FILE: keep-ui/app/(keep)/mapping/layout.tsx
  function Layout (line 1) | function Layout({ children }: { children: any }) {

FILE: keep-ui/app/(keep)/mapping/mapping.tsx
  function Mapping (line 15) | function Mapping() {

FILE: keep-ui/app/(keep)/mapping/models.tsx
  type MappingRule (line 1) | interface MappingRule {

FILE: keep-ui/app/(keep)/mapping/page.tsx
  function Page (line 3) | function Page() {

FILE: keep-ui/app/(keep)/mapping/rules-table.tsx
  type Props (line 33) | interface Props {
  function RulesTable (line 85) | function RulesTable({ mappings, editCallback }: Props) {

FILE: keep-ui/app/(keep)/mapping/run-mapping-modal.tsx
  type Props (line 16) | interface Props {
  function RunMappingModal (line 22) | function RunMappingModal({ ruleId, isOpen, onClose }: Props) {

FILE: keep-ui/app/(keep)/not-found.tsx
  function NotFound (line 8) | function NotFound() {

FILE: keep-ui/app/(keep)/notifications-hub/layout.tsx
  function Layout (line 3) | function Layout({ children }: { children: any }) {

FILE: keep-ui/app/(keep)/notifications-hub/page.tsx
  function Page (line 3) | function Page() {

FILE: keep-ui/app/(keep)/providers/filter-context/constants.ts
  constant PROVIDER_LABELS (line 3) | const PROVIDER_LABELS: Record<TProviderLabels, string> = {
  constant PROVIDER_LABELS_KEYS (line 13) | const PROVIDER_LABELS_KEYS = Object.keys(PROVIDER_LABELS);

FILE: keep-ui/app/(keep)/providers/filter-context/types.ts
  type IFilterContext (line 4) | interface IFilterContext {

FILE: keep-ui/app/(keep)/providers/form-fields.tsx
  function getRequiredConfigs (line 34) | function getRequiredConfigs(
  function getOptionalConfigs (line 43) | function getOptionalConfigs(
  function getConfigGroup (line 53) | function getConfigGroup(type: "config_main_group" | "config_sub_group") {
  function GroupFields (line 71) | function GroupFields({
  function FormField (line 143) | function FormField({
  function TextField (line 234) | function TextField({
  function SelectField (line 290) | function SelectField({
  function FileField (line 327) | function FileField({
  function KVForm (line 385) | function KVForm({
  function SwitchInput (line 483) | function SwitchInput({
  function FieldLabel (line 506) | function FieldLabel({

FILE: keep-ui/app/(keep)/providers/form-validation.ts
  type URLOptions (line 4) | type URLOptions = {
  type ValidatorRes (line 14) | type ValidatorRes = { success: true } | { success: false; msg: string };
  function mergeOptions (line 26) | function mergeOptions<T extends Record<string, unknown>>(
  function getProtocolError (line 49) | function getProtocolError(protocols: URLOptions["protocols"]) {
  function isFQDN (line 71) | function isFQDN(str: string, options?: Partial<URLOptions>): ValidatorRes {
  function isIP (line 109) | function isIP(str: string) {
  function validateHost (line 114) | function validateHost(hostname: string, opts: URLOptions): ValidatorRes {
  function isURL (line 143) | function isURL(str: string, options?: Partial<URLOptions>): ValidatorRes {
  function getBaseUrlSchema (line 205) | function getBaseUrlSchema(options?: Partial<URLOptions>) {
  function getZodSchema (line 218) | function getZodSchema(fields: Provider["config"], installed: boolean) {

FILE: keep-ui/app/(keep)/providers/layout.tsx
  function ProvidersLayout (line 9) | function ProvidersLayout({ children }: PropsWithChildren) {

FILE: keep-ui/app/(keep)/providers/oauth2/[providerType]/page.tsx
  function InstallFromOAuth (line 5) | async function InstallFromOAuth(props: {

FILE: keep-ui/app/(keep)/providers/page.client.tsx
  function ProvidersPage (line 115) | function ProvidersPage({

FILE: keep-ui/app/(keep)/providers/page.tsx
  function Page (line 3) | async function Page(props: {

FILE: keep-ui/app/(keep)/providers/provider-form.tsx
  type HealthResults (line 75) | type HealthResults = {
  type ProviderFormProps (line 88) | type ProviderFormProps = {
  function getInitialFormValues (line 103) | function getInitialFormValues(provider: Provider, isHealthCheck?: boolea...
  function installWebhook (line 183) | function installWebhook(provider: Provider) {
  function handleOauth (line 208) | async function handleOauth() {
  function revalidateScopes (line 237) | function revalidateScopes() {
  function deleteProvider (line 253) | async function deleteProvider() {
  function handleFormChange (line 267) | function handleFormChange(key: string, value: ProviderFormValue) {
  function validate (line 314) | function validate(data?: ProviderFormData) {
  function submit (line 343) | async function submit(requestUrl: string, method: string = "POST") {
  function handleSubmitError (line 371) | async function handleSubmitError(apiError: unknown) {
  function setApiError (line 397) | function setApiError(error: string) {
  function handleUpdateClick (line 411) | async function handleUpdateClick() {
  function handleConnectClick (line 435) | async function handleConnectClick() {

FILE: keep-ui/app/(keep)/providers/provider-logs.tsx
  type ProviderLogsProps (line 8) | interface ProviderLogsProps {
  constant LOG_LEVEL_COLORS (line 12) | const LOG_LEVEL_COLORS = {

FILE: keep-ui/app/(keep)/providers/provider-semi-automated.tsx
  type WebhookSettings (line 11) | interface WebhookSettings {
  type Props (line 17) | interface Props {

FILE: keep-ui/app/(keep)/providers/provider-tile.tsx
  type Props (line 25) | interface Props {
  function getIconForTag (line 94) | function getIconForTag(tag: TProviderLabels) {
  function ProviderTile (line 113) | function ProviderTile({ provider, onClick }: Props) {

FILE: keep-ui/app/(keep)/rules/CorrelationSidebar/AlertsFoundBadge.tsx
  type AlertsFoundBadgeProps (line 5) | type AlertsFoundBadgeProps = {
  function renderFoundAlertsText (line 18) | function renderFoundAlertsText() {
  function getNotFoundText (line 36) | function getNotFoundText() {

FILE: keep-ui/app/(keep)/rules/CorrelationSidebar/CorrelationForm.tsx
  type CorrelationFormProps (line 21) | type CorrelationFormProps = {

FILE: keep-ui/app/(keep)/rules/CorrelationSidebar/CorrelationSidebarBody.tsx
  type CorrelationSidebarBodyProps (line 21) | type CorrelationSidebarBodyProps = {

FILE: keep-ui/app/(keep)/rules/CorrelationSidebar/CorrelationSidebarHeader.tsx
  type CorrelationSidebarHeaderProps (line 6) | type CorrelationSidebarHeaderProps = {

FILE: keep-ui/app/(keep)/rules/CorrelationSidebar/CorrelationSubmission.tsx
  type CorrelationSubmissionProps (line 6) | type CorrelationSubmissionProps = {

FILE: keep-ui/app/(keep)/rules/CorrelationSidebar/DeleteRule.tsx
  type DeleteRuleCellProps (line 8) | type DeleteRuleCellProps = {

FILE: keep-ui/app/(keep)/rules/CorrelationSidebar/RuleFields.tsx
  constant DEFAULT_OPERATORS (line 27) | const DEFAULT_OPERATORS = defaultOperators.filter((operator) =>
  constant OPERATORS_FORCE_TYPE_CAST (line 48) | const OPERATORS_FORCE_TYPE_CAST = {
  constant DEFAULT_FIELDS (line 55) | const DEFAULT_FIELDS: QueryField[] = [
  type FieldProps (line 61) | type FieldProps = {
  type RuleFieldProps (line 198) | type RuleFieldProps = {

FILE: keep-ui/app/(keep)/rules/CorrelationSidebar/convert-cel-ast-to-query-builder-ast/convert-cel-ast-to-query-builder-ast.function.ts
  function mapOperator (line 5) | function mapOperator(op: string): string {
  function visitUnaryNode (line 30) | function visitUnaryNode(node: CelAst.UnaryNode): DefaultRuleGroupType {
  function visitComparisonNode (line 81) | function visitComparisonNode(
  function visitLogicalNode (line 120) | function visitLogicalNode(node: CelAst.LogicalNode): DefaultRuleGroupType {
  function visitCelAstNode (line 154) | function visitCelAstNode(node: CelAst.Node): DefaultRuleGroupType {
  function convertCelAstToQueryBuilderAst (line 174) | function convertCelAstToQueryBuilderAst(

FILE: keep-ui/app/(keep)/rules/CorrelationSidebar/index.tsx
  constant TIMEFRAME_UNITS_FROM_SECONDS (line 10) | const TIMEFRAME_UNITS_FROM_SECONDS = {
  constant DEFAULT_CORRELATION_FORM_VALUES (line 17) | const DEFAULT_CORRELATION_FORM_VALUES: CorrelationFormType = {
  type CorrelationSidebarProps (line 47) | type CorrelationSidebarProps = {

FILE: keep-ui/app/(keep)/rules/CorrelationSidebar/timeframe-constants.ts
  constant TIMEFRAME_UNITS_TO_SECONDS (line 1) | const TIMEFRAME_UNITS_TO_SECONDS = {

FILE: keep-ui/app/(keep)/rules/CorrelationSidebar/types.ts
  type CorrelationFormType (line 3) | type CorrelationFormType = {

FILE: keep-ui/app/(keep)/rules/CorrelationSidebar/useMatchingAlerts.ts
  function useMatchingAlerts (line 6) | function useMatchingAlerts(rules: RuleGroupType | undefined) {

FILE: keep-ui/app/(keep)/rules/CorrelationTable.tsx
  type CorrelationTableProps (line 30) | type CorrelationTableProps = {

FILE: keep-ui/app/(keep)/rules/GroupedByCel.tsx
  type GroupedByCellProps (line 6) | type GroupedByCellProps = {
  function renderFields (line 19) | function renderFields(fields: string[]): React.JSX.Element[] | React.JSX...

FILE: keep-ui/app/(keep)/rules/page.tsx
  function Page (line 3) | function Page() {

FILE: keep-ui/app/(keep)/settings/auth/api-key-settings.tsx
  type Props (line 27) | interface Props {
  type ApiKeyResponse (line 31) | interface ApiKeyResponse {
  function ApiKeySettings (line 35) | function ApiKeySettings({ selectedTab }: Props) {

FILE: keep-ui/app/(keep)/settings/auth/api-key-tab.tsx
  function APIKeysSubTab (line 3) | function APIKeysSubTab() {

FILE: keep-ui/app/(keep)/settings/auth/api-key-table.tsx
  type APIKey (line 17) | interface APIKey {
  type APIKeysTableProps (line 26) | interface APIKeysTableProps {
  function APIKeysTable (line 33) | function APIKeysTable({

FILE: keep-ui/app/(keep)/settings/auth/groups-sidebar.tsx
  type GroupSidebarProps (line 24) | interface GroupSidebarProps {

FILE: keep-ui/app/(keep)/settings/auth/groups-tab.tsx
  function GroupsTab (line 26) | function GroupsTab() {

FILE: keep-ui/app/(keep)/settings/auth/groups-table.tsx
  type Group (line 14) | interface Group {
  type GroupsTableProps (line 21) | interface GroupsTableProps {
  function GroupsTable (line 28) | function GroupsTable({

FILE: keep-ui/app/(keep)/settings/auth/permissions-sidebar.tsx
  type PermissionSidebarProps (line 23) | interface PermissionSidebarProps {

FILE: keep-ui/app/(keep)/settings/auth/permissions-tab.tsx
  type Props (line 14) | interface Props {
  type PermissionEntity (line 18) | interface PermissionEntity {
  type ResourcePermission (line 23) | interface ResourcePermission {
  function PermissionsTab (line 30) | function PermissionsTab({ isDisabled = false }: Props) {

FILE: keep-ui/app/(keep)/settings/auth/permissions-table.tsx
  type PermissionsTableProps (line 13) | interface PermissionsTableProps {
  function PermissionsTable (line 19) | function PermissionsTable({

FILE: keep-ui/app/(keep)/settings/auth/roles-sidebar.tsx
  type RoleSidebarProps (line 15) | interface RoleSidebarProps {

FILE: keep-ui/app/(keep)/settings/auth/roles-tab.tsx
  type RolesTabProps (line 27) | interface RolesTabProps {
  function RolesTab (line 31) | function RolesTab({ customRolesAllowed }: RolesTabProps) {

FILE: keep-ui/app/(keep)/settings/auth/roles-table.tsx
  type RolesTableProps (line 16) | interface RolesTableProps {
  function RolesTable (line 23) | function RolesTable({

FILE: keep-ui/app/(keep)/settings/auth/sso-settings.tsx
  type SSOProvider (line 18) | interface SSOProvider {

FILE: keep-ui/app/(keep)/settings/auth/sso-tab.tsx
  function SSOSubTab (line 3) | function SSOSubTab() {

FILE: keep-ui/app/(keep)/settings/auth/types.ts
  type ApiKey (line 1) | interface ApiKey {

FILE: keep-ui/app/(keep)/settings/auth/users-settings.tsx
  type Props (line 22) | interface Props {
  type Config (line 28) | interface Config {
  function UsersSettings (line 32) | function UsersSettings({

FILE: keep-ui/app/(keep)/settings/auth/users-sidebar.tsx
  type UserSidebarProps (line 27) | interface UserSidebarProps {

FILE: keep-ui/app/(keep)/settings/auth/users-tab.tsx
  type Props (line 4) | interface Props {
  function UserTab (line 10) | function UserTab({

FILE: keep-ui/app/(keep)/settings/auth/users-table.tsx
  type UsersTableProps (line 19) | interface UsersTableProps {
  function UsersTable (line 30) | function UsersTable({

FILE: keep-ui/app/(keep)/settings/create-api-key-modal.tsx
  type CreateApiKeyModalProps (line 16) | interface CreateApiKeyModalProps {
  function CreateApiKeyModal (line 23) | function CreateApiKeyModal({

FILE: keep-ui/app/(keep)/settings/layout.tsx
  function Layout (line 4) | function Layout({ children }: { children: any }) {

FILE: keep-ui/app/(keep)/settings/models.tsx
  type User (line 1) | interface User {
  type Group (line 12) | interface Group {
  type Permission (line 20) | interface Permission {
  type Role (line 30) | interface Role {
  type Scope (line 38) | interface Scope {

FILE: keep-ui/app/(keep)/settings/page.tsx
  function Page (line 4) | function Page() {

FILE: keep-ui/app/(keep)/settings/provider-images/page.tsx
  function ProviderImagesPage (line 3) | function ProviderImagesPage() {

FILE: keep-ui/app/(keep)/settings/provider-images/provider-image-list.tsx
  function ProviderImagesList (line 19) | function ProviderImagesList() {

FILE: keep-ui/app/(keep)/settings/provider-images/provider-image-uploader.tsx
  type Props (line 9) | interface Props {
  function ProviderImageUploader (line 17) | function ProviderImageUploader({

FILE: keep-ui/app/(keep)/settings/provider-images/provider-images-settings.tsx
  function ProviderImagesSettings (line 12) | function ProviderImagesSettings() {

FILE: keep-ui/app/(keep)/settings/settings.client.tsx
  function SettingsPage (line 40) | function SettingsPage() {

FILE: keep-ui/app/(keep)/settings/smtp-settings.tsx
  type SMTPSettings (line 10) | interface SMTPSettings {
  type SMTPSettingsErrors (line 20) | interface SMTPSettingsErrors {
  type TestResult (line 29) | interface TestResult {
  type Props (line 35) | interface Props {
  function SMTPSettingsForm (line 43) | function SMTPSettingsForm({ selectedTab }: Props) {

FILE: keep-ui/app/(keep)/settings/webhook-settings.tsx
  type Webhook (line 30) | interface Webhook {
  type Props (line 36) | interface Props {
  function WebhookSettings (line 40) | function WebhookSettings({ selectedTab }: Props) {

FILE: keep-ui/app/(keep)/topology/TopologySearchContext.tsx
  type TopologySearchContextType (line 4) | type TopologySearchContextType = {
  function useTopologySearchContext (line 21) | function useTopologySearchContext() {

FILE: keep-ui/app/(keep)/topology/api/index.ts
  function buildTopologyUrl (line 4) | function buildTopologyUrl({
  function getApplications (line 30) | async function getApplications(api: ApiClient) {
  function getTopology (line 35) | async function getTopology(
  function pullTopology (line 51) | async function pullTopology(api: ApiClient) {

FILE: keep-ui/app/(keep)/topology/layout.tsx
  function Layout (line 3) | function Layout({ children }: { children: any }) {

FILE: keep-ui/app/(keep)/topology/lib/badge-colors.ts
  function uuidToArrayItem (line 1) | function uuidToArrayItem(uuidString: string, array: any[]): number {
  function getColorForUUID (line 9) | function getColorForUUID(id: string) {

FILE: keep-ui/app/(keep)/topology/model/TopologyPollingContext.tsx
  type TopologyUpdate (line 7) | interface TopologyUpdate {
  function useTopologyPollingContext (line 43) | function useTopologyPollingContext() {

FILE: keep-ui/app/(keep)/topology/model/models.ts
  type TopologyServiceDependency (line 5) | interface TopologyServiceDependency {
  type TopologyService (line 12) | interface TopologyService {
  type TopologyServiceWithMutator (line 36) | interface TopologyServiceWithMutator extends TopologyService {
  type ServiceNodeType (line 42) | type ServiceNodeType = Node<
  type TopologyNode (line 47) | type TopologyNode = ServiceNodeType | Node;
  type TopologyServiceMinimal (line 49) | type TopologyServiceMinimal = {
  type TopologyApplicationMinimal (line 55) | type TopologyApplicationMinimal = {
  type TopologyApplication (line 60) | type TopologyApplication = {

FILE: keep-ui/app/(keep)/topology/model/useTopology.ts
  constant TOPOLOGY_URL (line 8) | const TOPOLOGY_URL = `/topology`;
  type UseTopologyOptions (line 10) | type UseTopologyOptions = {

FILE: keep-ui/app/(keep)/topology/model/useTopologyApplications.ts
  type UseTopologyApplicationsOptions (line 11) | type UseTopologyApplicationsOptions = {
  constant TOPOLOGY_APPLICATIONS_URL (line 16) | const TOPOLOGY_APPLICATIONS_URL = `/topology/applications`;
  function useTopologyApplications (line 18) | function useTopologyApplications(

FILE: keep-ui/app/(keep)/topology/page.tsx
  type PageProps (line 13) | type PageProps = {
  function Page (line 21) | async function Page(props: PageProps) {

FILE: keep-ui/app/(keep)/topology/topology-client.tsx
  function TopologyPageClient (line 21) | function TopologyPageClient({

FILE: keep-ui/app/(keep)/topology/ui/TopologySearchAutocomplete.tsx
  type BaseProps (line 16) | type BaseProps = {
  type WithApplications (line 23) | type WithApplications = BaseProps &
  type WithoutApplications (line 31) | type WithoutApplications = BaseProps &
  type TopologySearchAutocompleteProps (line 36) | type TopologySearchAutocompleteProps = WithApplications | WithoutApplica...
  function TopologySearchAutocomplete (line 38) | function TopologySearchAutocomplete({

FILE: keep-ui/app/(keep)/topology/ui/applications/application-card.tsx
  function ApplicationCard (line 4) | function ApplicationCard({

FILE: keep-ui/app/(keep)/topology/ui/applications/application-modal.tsx
  type BaseProps (line 5) | type BaseProps = {
  type ApplicationModalCreateProps (line 10) | type ApplicationModalCreateProps = BaseProps & {
  type ApplicationModalEditProps (line 17) | type ApplicationModalEditProps = BaseProps & {
  function ApplicationModal (line 24) | function ApplicationModal({

FILE: keep-ui/app/(keep)/topology/ui/applications/applications-list.tsx
  type ModalState (line 19) | type ModalState = {
  function ApplicationsList (line 31) | function ApplicationsList({

FILE: keep-ui/app/(keep)/topology/ui/applications/create-or-update-application-form.tsx
  type FormErrors (line 12) | type FormErrors = {
  type BaseProps (line 18) | type BaseProps = {
  type CreateProps (line 22) | type CreateProps = BaseProps & {
  type UpdateProps (line 29) | type UpdateProps = BaseProps & {
  type CreatOrUpdateApplicationFormProps (line 36) | type CreatOrUpdateApplicationFormProps = CreateProps | UpdateProps;
  function CreateOrUpdateApplicationForm (line 38) | function CreateOrUpdateApplicationForm({

FILE: keep-ui/app/(keep)/topology/ui/map/AddEditNodeSidePanel.tsx
  type AddNodeSidePanelProps (line 9) | interface AddNodeSidePanelProps {
  type TopologyServiceFormProps (line 16) | type TopologyServiceFormProps = {
  function AddEditNodeSidePanel (line 33) | function AddEditNodeSidePanel({

FILE: keep-ui/app/(keep)/topology/ui/map/application-node.tsx
  function ApplicationNode (line 33) | function ApplicationNode({ id, data, selected }: NodeProps) {

FILE: keep-ui/app/(keep)/topology/ui/map/getLayoutedElements.ts
  function getLayoutedElements (line 6) | function getLayoutedElements(nodes: TopologyNode[], edges: Edge[]) {

FILE: keep-ui/app/(keep)/topology/ui/map/getNodesAndEdgesFromTopologyData.ts
  function getNodesAndEdgesFromTopologyData (line 18) | function getNodesAndEdgesFromTopologyData(

FILE: keep-ui/app/(keep)/topology/ui/map/manage-selection.tsx
  function ManageSelection (line 28) | function ManageSelection({

FILE: keep-ui/app/(keep)/topology/ui/map/service-node.tsx
  constant THRESHOLD (line 10) | const THRESHOLD = 5;
  function ServiceDetailsTooltip (line 12) | function ServiceDetailsTooltip({ data }: { data: TopologyService }) {
  function ServiceNode (line 73) | function ServiceNode({ data, selected }: NodeProps<ServiceNodeType>) {

FILE: keep-ui/app/(keep)/topology/ui/map/topology-map.tsx
  type TopologyMapProps (line 82) | type TopologyMapProps = {
  type MenuItem (line 93) | interface MenuItem {
  function TopologyMap (line 99) | function TopologyMap({

FILE: keep-ui/app/(keep)/workflows/[workflow_id]/layout.tsx
  function Layout (line 5) | async function Layout(props: {

FILE: keep-ui/app/(keep)/workflows/[workflow_id]/page.tsx
  function Page (line 5) | async function Page(props: {

FILE: keep-ui/app/(keep)/workflows/[workflow_id]/runs/[workflow_execution_id]/page.tsx
  function WorkflowExecutionPage (line 5) | async function WorkflowExecutionPage(props: {

FILE: keep-ui/app/(keep)/workflows/[workflow_id]/table-filters.tsx
  type TableFiltersProps (line 7) | interface TableFiltersProps {
  type Filters (line 11) | type Filters = {
  type PopoverContentProps (line 18) | interface PopoverContentProps {

FILE: keep-ui/app/(keep)/workflows/[workflow_id]/versions/[revision]/page.tsx
  function WorkflowVersionPage (line 8) | function WorkflowVersionPage() {

FILE: keep-ui/app/(keep)/workflows/[workflow_id]/workflow-breadcrumbs.tsx
  function WorkflowBreadcrumbs (line 9) | function WorkflowBreadcrumbs({ workflowId }: { workflowId: string }) {

FILE: keep-ui/app/(keep)/workflows/[workflow_id]/workflow-detail-header.tsx
  function WorkflowDetailHeader (line 9) | function WorkflowDetailHeader({

FILE: keep-ui/app/(keep)/workflows/[workflow_id]/workflow-detail-page.tsx
  constant TABS_KEYS (line 35) | const TABS_KEYS = ["overview", "builder", "yaml", "versions", "secrets"];
  function getTabIndex (line 37) | function getTabIndex(tabKey: string) {
  function WorkflowDetailPage (line 45) | function WorkflowDetailPage({

FILE: keep-ui/app/(keep)/workflows/[workflow_id]/workflow-executions-table.tsx
  type Pagination (line 36) | interface Pagination {
  type WorkflowExecutionsTableProps (line 41) | interface WorkflowExecutionsTableProps {
  function WorkflowExecutionRowMenu (line 49) | function WorkflowExecutionRowMenu({
  function WorkflowExecutionsTable (line 99) | function WorkflowExecutionsTable({

FILE: keep-ui/app/(keep)/workflows/[workflow_id]/workflow-overview-skeleton.tsx
  function WorkflowOverviewSkeleton (line 3) | function WorkflowOverviewSkeleton() {

FILE: keep-ui/app/(keep)/workflows/[workflow_id]/workflow-overview.tsx
  type Pagination (line 13) | interface Pagination {
  function StatsCard (line 18) | function StatsCard({ children }: { children: any }) {
  function WorkflowOverview (line 26) | function WorkflowOverview({

FILE: keep-ui/app/(keep)/workflows/[workflow_id]/workflow-providers.tsx
  function WorkflowProviders (line 61) | function WorkflowProviders({ workflow }: { workflow: Workflow }) {

FILE: keep-ui/app/(keep)/workflows/[workflow_id]/workflow-sync-status.tsx
  type WorkflowSyncStatusProps (line 7) | interface WorkflowSyncStatusProps {
  function WorkflowSyncStatus (line 14) | function WorkflowSyncStatus({

FILE: keep-ui/app/(keep)/workflows/[workflow_id]/workflow-versions.tsx
  function WorkflowVersions (line 13) | function WorkflowVersions({

FILE: keep-ui/app/(keep)/workflows/builder/[workflowId]/page.tsx
  type WorkflowRawResponse (line 5) | type WorkflowRawResponse = {
  function PageWithId (line 9) | async function PageWithId(props: {

FILE: keep-ui/app/(keep)/workflows/builder/layout.tsx
  function Layout (line 6) | function Layout({ children }: { children: React.ReactNode }) {

FILE: keep-ui/app/(keep)/workflows/builder/page.tsx
  type PageProps (line 4) | type PageProps = {
  function WorkflowBuilderPage (line 9) | async function WorkflowBuilderPage(props: PageProps) {

FILE: keep-ui/app/(keep)/workflows/create-workflow-modal.tsx
  type CreateWorkflowModalProps (line 8) | interface CreateWorkflowModalProps {

FILE: keep-ui/app/(keep)/workflows/existing-workflows-state.tsx
  function ExistingWorkflowsState (line 46) | function ExistingWorkflowsState({

FILE: keep-ui/app/(keep)/workflows/no-workflows-state.tsx
  function NoWorkflowsState (line 12) | function NoWorkflowsState({}: {

FILE: keep-ui/app/(keep)/workflows/page.tsx
  function Page (line 7) | async function Page() {

FILE: keep-ui/app/(keep)/workflows/preview/[workflowId]/page.tsx
  function PageWithId (line 10) | function PageWithId(

FILE: keep-ui/app/(keep)/workflows/preview/page.tsx
  type PageProps (line 7) | type PageProps = {
  function Page (line 12) | function Page(props: PageProps) {

FILE: keep-ui/app/(keep)/workflows/upload-workflows-modal.tsx
  constant EXAMPLE_WORKFLOW_DEFINITIONS (line 11) | const EXAMPLE_WORKFLOW_DEFINITIONS = {
  type ExampleWorkflowKey (line 50) | type ExampleWorkflowKey = keyof typeof EXAMPLE_WORKFLOW_DEFINITIONS;
  type UploadWorkflowsModalProps (line 52) | interface UploadWorkflowsModalProps {
  function handleWorkflowDefinitionString (line 83) | function handleWorkflowDefinitionString(
  function handleStaticExampleSelect (line 101) | function handleStaticExampleSelect(exampleKey: ExampleWorkflowKey) {

FILE: keep-ui/app/(keep)/workflows/workflow-graph.tsx
  type BarChartOptions (line 33) | type BarChartOptions = Parameters<typeof Bar>[0]["options"];
  function WorkflowGraph (line 95) | function WorkflowGraph({

FILE: keep-ui/app/(keep)/workflows/workflow-menu.tsx
  type WorkflowMenuProps (line 14) | interface WorkflowMenuProps {
  function WorkflowMenu (line 27) | function WorkflowMenu({

FILE: keep-ui/app/(keep)/workflows/workflow-templates/workflow-templates.tsx
  type WorkflowTemplatesProps (line 11) | interface WorkflowTemplatesProps {}
  function renderBody (line 53) | function renderBody() {

FILE: keep-ui/app/(keep)/workflows/workflow-tile.tsx
  function TriggerTile (line 32) | function TriggerTile({ trigger }: { trigger: Trigger }) {
  function WorkflowTile (line 57) | function WorkflowTile({ workflow }: { workflow: Workflow }) {

FILE: keep-ui/app/(keep)/workflows/workflow-utils.ts
  function getRandomStatus (line 65) | function getRandomStatus() {

FILE: keep-ui/app/(keep)/workflows/workflows-steps.tsx
  function WorkflowSteps (line 7) | function WorkflowSteps({ workflow }: { workflow: MockWorkflow }) {

FILE: keep-ui/app/(keep)/workflows/workflows.page.tsx
  function WorkflowsPage (line 9) | function WorkflowsPage({

FILE: keep-ui/app/(signin)/error/authEnvUtils.tsx
  type AuthEnvVars (line 4) | interface AuthEnvVars {
  function getAuthTypeEnvVars (line 8) | function getAuthTypeEnvVars(authType: string | undefined): AuthEnvVars {

FILE: keep-ui/app/(signin)/error/error-client.tsx
  type ErrorType (line 5) | type ErrorType =
  type AuthErrorProps (line 11) | interface AuthErrorProps {

FILE: keep-ui/app/(signin)/error/page.tsx
  function ErrorPage (line 5) | async function ErrorPage(

FILE: keep-ui/app/(signin)/layout.tsx
  function RootLayout (line 9) | function RootLayout({

FILE: keep-ui/app/(signin)/mobile/GithubButton.tsx
  function GithubButton (line 7) | function GithubButton() {

FILE: keep-ui/app/(signin)/mobile/page.tsx
  function MobileLanding (line 7) | function MobileLanding() {

FILE: keep-ui/app/(signin)/signin/SignInForm.tsx
  type Provider (line 11) | interface Provider {
  type Providers (line 19) | interface Providers {
  type SignInFormInputs (line 28) | interface SignInFormInputs {
  function SignInForm (line 33) | function SignInForm({

FILE: keep-ui/app/(signin)/signin/page.tsx
  function SignInPage (line 6) | function SignInPage(props: {

FILE: keep-ui/app/actions/authactions.ts
  function authenticate (line 7) | async function authenticate(username: string, password: string) {
  function revalidateAfterAuth (line 63) | async function revalidateAfterAuth() {

FILE: keep-ui/app/api/aws-marketplace/route.ts
  function POST (line 4) | async function POST(request: NextRequest) {

FILE: keep-ui/app/api/copilotkit/route.ts
  function initializeCopilotRuntime (line 10) | function initializeCopilotRuntime() {

FILE: keep-ui/app/api/healthcheck/route.ts
  function GET (line 3) | async function GET() {

FILE: keep-ui/app/auth-provider.tsx
  type Window (line 7) | interface Window {
  type Props (line 12) | type Props = {

FILE: keep-ui/app/config-provider.tsx
  function ConfigProvider (line 10) | function ConfigProvider({

FILE: keep-ui/app/global-error.tsx
  function GlobalError (line 5) | function GlobalError({

FILE: keep-ui/app/not-authorized.tsx
  function NotAuthorized (line 8) | function NotAuthorized({ message }: { message?: string }) {

FILE: keep-ui/app/posthog-provider.tsx
  function PHProvider (line 8) | function PHProvider({ children }: { children: React.ReactNode }) {

FILE: keep-ui/app/raw/workflows/[workflow_filename]/route.ts
  function GET (line 3) | async function GET(

FILE: keep-ui/auth.config.ts
  class BackendRefusedError (line 22) | class BackendRefusedError extends AuthError {
  function runtimeEnv (line 30) | function runtimeEnv(key: string): string | undefined {
  function refreshAccessToken (line 54) | async function refreshAccessToken(token: any) {
  method authorize (line 146) | async authorize(credentials): Promise<User | null> {
  method authorize (line 189) | async authorize(credentials): Promise<User> {
  method authorize (line 238) | async authorize(credentials, request): Promise<User | null> {
  method authorized (line 312) | authorized({ auth, request: { nextUrl } }) {

FILE: keep-ui/auth.ts
  method authorize (line 18) | async authorize(credentials, req): Promise<User | null> {
  function proxyFetch (line 82) | function proxyFetch(

FILE: keep-ui/components/LinkWithIcon.tsx
  type LinkWithIconProps (line 10) | type LinkWithIconProps = {

FILE: keep-ui/components/LogViewer.tsx
  type Props (line 4) | interface Props {
  function LogViewer (line 8) | function LogViewer({ logs }: Props) {

FILE: keep-ui/components/SidePanel.tsx
  type SidePanelProps (line 4) | interface SidePanelProps {

FILE: keep-ui/components/banners/BannerBase.tsx
  type KeepBannerProps (line 8) | type KeepBannerProps = {

FILE: keep-ui/components/filters/GenericFilters.tsx
  type Filter (line 11) | type Filter = {
  type FiltersProps (line 24) | interface FiltersProps {
  type PopoverContentProps (line 28) | interface PopoverContentProps {
  function toArray (line 37) | function toArray(value: string | string[]) {
  function CustomSelect (line 47) | function CustomSelect({
  function getParsedValue (line 144) | function getParsedValue(filter: Filter) {
  function CustomDate (line 159) | function CustomDate({

FILE: keep-ui/components/navbar/AlertsLinks.tsx
  type AlertsLinksProps (line 23) | type AlertsLinksProps = {

FILE: keep-ui/components/navbar/DashboardLink.tsx
  type Dashboard (line 7) | interface Dashboard {
  type DashboardLinkProps (line 13) | type DashboardLinkProps = {

FILE: keep-ui/components/navbar/IncidentLinks.tsx
  type IncidentsLinksProps (line 17) | type IncidentsLinksProps = { session: Session | null };

FILE: keep-ui/components/navbar/Menu.tsx
  type CloseMenuOnRouteChangeProps (line 12) | type CloseMenuOnRouteChangeProps = {
  type MenuButtonProps (line 26) | type MenuButtonProps = {

FILE: keep-ui/components/navbar/Navbar.tsx
  function NavbarInner (line 13) | async function NavbarInner() {

FILE: keep-ui/components/navbar/NoiseReductionLinks.tsx
  type NoiseReductionLinksProps (line 21) | type NoiseReductionLinksProps = { session: Session | null };
  type TogglableLinkProps (line 23) | type TogglableLinkProps = {

FILE: keep-ui/components/navbar/Search.tsx
  constant NAVIGATION_OPTIONS (line 36) | const NAVIGATION_OPTIONS = [
  type SearchProps (line 93) | interface SearchProps {

FILE: keep-ui/components/navbar/SetSentryUser.tsx
  function SetSentryUser (line 6) | function SetSentryUser({ session }: { session: Session | null }) {

FILE: keep-ui/components/navbar/UserAvatar.tsx
  type Props (line 4) | interface Props {
  function UserAvatar (line 23) | function UserAvatar({ image, name, size = "sm", email }: Props) {

FILE: keep-ui/components/navbar/UserInfo.tsx
  constant ONBOARDING_FLOW_ID (line 18) | const ONBOARDING_FLOW_ID = "flow_FHDz1hit";
  type UserDropdownProps (line 20) | type UserDropdownProps = {
  type UserInfoProps (line 83) | type UserInfoProps = {

FILE: keep-ui/components/popover/GenericPopover.tsx
  type PopoverProps (line 13) | interface PopoverProps {

FILE: keep-ui/components/table/ExecutionsTable.tsx
  type Pagination (line 13) | interface Pagination {
  type Props (line 18) | interface Props {
  function ExecutionsTable (line 23) | function ExecutionsTable({ executions, setPagination }: Props) {

FILE: keep-ui/components/table/GenericTable.tsx
  type GenericTableProps (line 21) | interface GenericTableProps<T> {
  function GenericTable (line 33) | function GenericTable<T>({

FILE: keep-ui/components/table/Pagination.tsx
  type Props (line 13) | interface Props<T> {
  type OptionType (line 18) | interface OptionType {
  function Pagination (line 33) | function Pagination<T>({ table, isRefreshAllowed }: Props<T>) {

FILE: keep-ui/components/ui/AutocompleteInput.tsx
  type Option (line 7) | type Option<T> = {
  type AutocompleteInputProps (line 12) | type AutocompleteInputProps<T> = {
  function AutocompleteInput (line 20) | function AutocompleteInput<T>({

FILE: keep-ui/components/ui/Button.tsx
  type ButtonVariantType (line 5) | type ButtonVariantType = "destructive" | ButtonProps["variant"];
  function Button (line 7) | function Button({

FILE: keep-ui/components/ui/Calendar.tsx
  function cn (line 5) | function cn(...classes: (string | undefined)[]) {
  type CalendarSingleProps (line 9) | interface CalendarSingleProps {
  type CalendarRangeProps (line 18) | interface CalendarRangeProps {
  type CalendarProps (line 27) | type CalendarProps =
  function Calendar (line 49) | function Calendar({

FILE: keep-ui/components/ui/CreatableMultiSelect.tsx
  type OptionType (line 6) | type OptionType = { value: string; label: string };
  type CustomSelectProps (line 52) | type CustomSelectProps = SelectProps<OptionType, true, GroupBase<OptionT...
  type CreatableMultiSelectProps (line 76) | type CreatableMultiSelectProps = SelectProps<OptionType, true, GroupBase...

FILE: keep-ui/components/ui/DateRangePicker.tsx
  constant ONE_MINUTE (line 19) | const ONE_MINUTE = 60 * 1000;
  constant ONE_HOUR (line 20) | const ONE_HOUR = 60 * ONE_MINUTE;
  constant ONE_DAY (line 21) | const ONE_DAY = 24 * ONE_HOUR;
  type TimeFrame (line 23) | interface TimeFrame {
  type TimePreset (line 29) | interface TimePreset {
  type CategoryPreset (line 35) | interface CategoryPreset {
  type EnhancedDateRangePickerProps (line 40) | interface EnhancedDateRangePickerProps {
  function isQuickPresetRange (line 54) | function isQuickPresetRange(timeFrame: TimeFrame): boolean {
  function EnhancedDateRangePicker (line 104) | function EnhancedDateRangePicker({

FILE: keep-ui/components/ui/DateRangePickerV2.tsx
  constant ONE_MINUTE (line 19) | const ONE_MINUTE = 60 * 1000;
  constant ONE_HOUR (line 20) | const ONE_HOUR = 60 * ONE_MINUTE;
  constant ONE_DAY (line 21) | const ONE_DAY = 24 * ONE_HOUR;
  type AllTimeFrame (line 23) | interface AllTimeFrame {
  type RelativeTimeFrame (line 28) | interface RelativeTimeFrame {
  type AbsoluteTimeFrame (line 34) | interface AbsoluteTimeFrame {
  type TimeFrameV2 (line 40) | type TimeFrameV2 = AllTimeFrame | RelativeTimeFrame | AbsoluteTimeFrame;
  function areTimeframesEqual (line 42) | function areTimeframesEqual(
  type TimePreset (line 70) | interface TimePreset {
  type CategoryPreset (line 76) | interface CategoryPreset {
  type EnhancedDateRangePickerV2Props (line 81) | interface EnhancedDateRangePickerV2Props {
  function EnhancedDateRangePickerV2 (line 95) | function EnhancedDateRangePickerV2({

FILE: keep-ui/components/ui/EmptyStateImage.tsx
  type EmptyStateImageProps (line 6) | interface EmptyStateImageProps {
  function EmptyStateImage (line 13) | function EmptyStateImage({

FILE: keep-ui/components/ui/EmptyStateTable.tsx
  type EmptyStateTableProps (line 5) | interface EmptyStateTableProps {
  function EmptyStateTable (line 12) | function EmptyStateTable({

FILE: keep-ui/components/ui/ImagePreviewTooltip.tsx
  type TooltipPosition (line 3) | type TooltipPosition = { x: number; y: number } | null;

FILE: keep-ui/components/ui/Link.tsx
  type LinkProps (line 6) | type LinkProps = {
  function Link (line 13) | function Link({ icon, iconPosition = "left", ...props }: LinkProps) {

FILE: keep-ui/components/ui/Modal.tsx
  function Modal (line 13) | function Modal({

FILE: keep-ui/components/ui/ResizableColumns.tsx
  type ResizableColumnsProps (line 3) | interface ResizableColumnsProps {

FILE: keep-ui/components/ui/RootCauseAnalysis.tsx
  type RCAPoint (line 6) | interface RCAPoint {
  function RootCauseAnalysis (line 11) | function RootCauseAnalysis({

FILE: keep-ui/components/ui/ShortNumber.tsx
  type Props (line 8) | interface Props {
  function ShortNumber (line 12) | function ShortNumber({ value }: Props) {

FILE: keep-ui/components/ui/Textarea.tsx
  function Textarea (line 4) | function Textarea({ className, ...props }: TextareaProps) {

FILE: keep-ui/components/ui/useTimeframeState.ts
  function getTimeframeInitialState (line 23) | function getTimeframeInitialState(
  function deleteTimeframeParams (line 78) | function deleteTimeframeParams(searchParams: URLSearchParams) {
  function useTimeframeState (line 84) | function useTimeframeState({

FILE: keep-ui/entities/alerts/lib/getTabsFromPreset.ts
  function getTabsFromPreset (line 8) | function getTabsFromPreset(preset: Preset): any[] {

FILE: keep-ui/entities/alerts/model/constants.ts
  constant DEFAULT_ROW_STYLE (line 2) | const DEFAULT_ROW_STYLE = "default";

FILE: keep-ui/entities/alerts/model/types.ts
  type Severity (line 1) | enum Severity {
  type Status (line 26) | enum Status {
  type AlertDto (line 34) | interface AlertDto {
  type AlertToWorkflowExecution (line 73) | interface AlertToWorkflowExecution {
  type ViewedAlert (line 112) | interface ViewedAlert {
  type AuditEvent (line 117) | type AuditEvent = {
  type CommentMentionDto (line 127) | interface CommentMentionDto {
  type AlertsQuery (line 131) | interface AlertsQuery {

FILE: keep-ui/entities/alerts/model/useAlertRowStyle.ts
  type RowStyle (line 4) | type RowStyle = "relaxed" | "default";

FILE: keep-ui/entities/alerts/model/useAlertTableTheme.ts
  function useAlertTableTheme (line 4) | function useAlertTableTheme() {

FILE: keep-ui/entities/alerts/model/useAvailableAlertFields.ts
  constant DAY (line 5) | const DAY = 3600 * 24;
  constant MAX_DEPTH (line 6) | const MAX_DEPTH = 10;

FILE: keep-ui/entities/alerts/model/useSeverityMapping.ts
  type SeverityMappingConfig (line 5) | interface SeverityMappingConfig {
  function useSeverityMapping (line 17) | function useSeverityMapping() {
  function getMappedColor (line 28) | function getMappedColor(

FILE: keep-ui/entities/alerts/ui/AlertName/AlertName.tsx
  type Props (line 6) | interface Props {
  function AlertName (line 12) | function AlertName({ alert, className, expanded }: Props) {

FILE: keep-ui/entities/alerts/ui/alert-severity.tsx
  type Props (line 10) | interface Props {
  function AlertSeverity (line 14) | function AlertSeverity({ severity }: Props) {

FILE: keep-ui/entities/incidents/api/incidents.ts
  type Filters (line 4) | interface Filters {
  type GetIncidentsParams (line 12) | type GetIncidentsParams = {
  function buildIncidentsUrl (line 21) | function buildIncidentsUrl(params: GetIncidentsParams) {
  function getIncidents (line 43) | async function getIncidents(api: ApiClient, params: GetIncidentsParams) {
  function getIncident (line 48) | async function getIncident(api: ApiClient, id: string) {

FILE: keep-ui/entities/incidents/lib/ticketing-utils.ts
  type LinkedTicket (line 4) | interface LinkedTicket {
  function getProviderBaseUrl (line 13) | function getProviderBaseUrl(provider: Provider): string {
  function getTicketViewUrl (line 28) | function getTicketViewUrl(incident: IncidentDto, provider: Provider): st...
  function getTicketCreateUrl (line 38) | function getTicketCreateUrl(provider: Provider, description: string = ""...
  function findLinkedTicket (line 59) | function findLinkedTicket(incident: any, ticketingProviders: Provider[])...
  function canCreateTickets (line 76) | function canCreateTickets(provider: Provider): boolean {
  function getTicketEnrichmentKey (line 83) | function getTicketEnrichmentKey(provider: Provider): string {

FILE: keep-ui/entities/incidents/lib/utils.ts
  function getIncidentName (line 8) | function getIncidentName(incident: IncidentDto) {
  function getIncidentNameWithCreationTime (line 14) | function getIncidentNameWithCreationTime(incident: IncidentDto) {
  function getIncidentSeverityIconAndColor (line 18) | function getIncidentSeverityIconAndColor(

FILE: keep-ui/entities/incidents/model/models.ts
  type Status (line 4) | enum Status {
  type Severity (line 12) | enum Severity {
  constant DEFAULT_INCIDENTS_CHECKED_OPTIONS (line 30) | const DEFAULT_INCIDENTS_CHECKED_OPTIONS = [
  constant DEFAULT_INCIDENTS_CEL (line 34) | const DEFAULT_INCIDENTS_CEL = `is_candidate == false && (status in [${DE...
  constant DEFAULT_INCIDENTS_SORTING (line 36) | const DEFAULT_INCIDENTS_SORTING = { id: "creation_time", desc: true };
  constant DEFAULT_INCIDENTS_PAGE_SIZE (line 37) | const DEFAULT_INCIDENTS_PAGE_SIZE = 20;
  constant INCIDENT_PAGINATION_OPTIONS (line 38) | const INCIDENT_PAGINATION_OPTIONS = [
  type IncidentDto (line 45) | interface IncidentDto {
  type IncidentCandidateDto (line 78) | interface IncidentCandidateDto {
  type PaginatedIncidentsDto (line 89) | interface PaginatedIncidentsDto {
  type PaginatedIncidentAlertsDto (line 96) | interface PaginatedIncidentAlertsDto {
  type IncidentsMetaDto (line 103) | interface IncidentsMetaDto {

FILE: keep-ui/entities/incidents/model/useIncidentActions.tsx
  type UseIncidentActionsValue (line 8) | type UseIncidentActionsValue = {
  type IncidentCreateDto (line 62) | type IncidentCreateDto = {
  type IncidentUpdateDto (line 70) | type IncidentUpdateDto = Partial<IncidentCreateDto> &
  function useIncidentActions (line 75) | function useIncidentActions(): UseIncidentActionsValue {

FILE: keep-ui/entities/incidents/ui/IncidentIconName/IncidentIconName.tsx
  function IncidentIconName (line 6) | function IncidentIconName({

FILE: keep-ui/entities/incidents/ui/IncidentSeverityBadge.tsx
  type Props (line 12) | interface Props {
  function IncidentSeverityBadge (line 17) | function IncidentSeverityBadge({ severity, size = "xs" }: Props) {

FILE: keep-ui/entities/incidents/ui/statuses.tsx
  constant STATUS_COLORS (line 12) | const STATUS_COLORS = {
  constant STATUS_ICONS (line 19) | const STATUS_ICONS = {
  function StatusIcon (line 62) | function StatusIcon({

FILE: keep-ui/entities/presets/model/constants.ts
  constant STATIC_PRESETS_NAMES (line 1) | const STATIC_PRESETS_NAMES = ["feed"];
  constant LOCAL_PRESETS_KEY (line 2) | const LOCAL_PRESETS_KEY = "presets-order";
  constant LOCAL_STATIC_PRESETS_KEY (line 3) | const LOCAL_STATIC_PRESETS_KEY = "static-presets-order";
  constant STATIC_PRESET_IDS (line 6) | const STATIC_PRESET_IDS = [

FILE: keep-ui/entities/presets/model/types.ts
  type Option (line 3) | interface Option {
  type Tag (line 8) | interface Tag {
  type ColumnConfiguration (line 13) | interface ColumnConfiguration {
  type Preset (line 21) | interface Preset {
  type TagPayload (line 35) | type TagPayload = {
  type PresetCreateUpdateDto (line 40) | type PresetCreateUpdateDto = {

FILE: keep-ui/entities/presets/model/usePresetActions.ts
  function createPresetBody (line 11) | function createPresetBody(data: PresetCreateUpdateDto) {
  function usePresetActions (line 34) | function usePresetActions() {

FILE: keep-ui/entities/presets/model/usePresetColumnConfig.ts
  type UsePresetColumnConfigOptions (line 8) | type UsePresetColumnConfigOptions = {
  constant DEFAULT_COLUMN_CONFIG (line 13) | const DEFAULT_COLUMN_CONFIG: ColumnConfiguration = {
  type UsePresetColumnConfigValue (line 106) | type UsePresetColumnConfigValue = ReturnType<

FILE: keep-ui/entities/presets/model/usePresetColumnState.ts
  type UsePresetColumnStateOptions (line 15) | interface UsePresetColumnStateOptions {
  type UsePresetColumnStateValue (line 268) | type UsePresetColumnStateValue = ReturnType<typeof usePresetColumnState>;

FILE: keep-ui/entities/presets/model/usePresetPolling.ts
  constant PRESET_POLLING_INTERVAL (line 5) | const PRESET_POLLING_INTERVAL = 5 * 1000;
  function usePresetPolling (line 7) | function usePresetPolling() {

FILE: keep-ui/entities/presets/model/usePresets.ts
  type UsePresetsOptions (line 15) | type UsePresetsOptions = {

FILE: keep-ui/entities/presets/model/useSilencedPresets.ts
  constant SILENCED_PRESETS_KEY (line 4) | const SILENCED_PRESETS_KEY = "silencedPresets";
  function useSilencedPresets (line 6) | function useSilencedPresets() {

FILE: keep-ui/entities/provider-images/model/useProviderImages.ts
  type CustomImage (line 5) | interface CustomImage {
  function useProviderImages (line 17) | function useProviderImages() {

FILE: keep-ui/entities/users/model/useUser.ts
  function useUser (line 3) | function useUser(email: string) {

FILE: keep-ui/entities/users/ui/UserStatefulAvatar.tsx
  function UserStatefulAvatar (line 7) | function UserStatefulAvatar({

FILE: keep-ui/entities/workflows/lib/extractWorkflowYamlDependencies.ts
  type WorkflowYamlDependencies (line 3) | type WorkflowYamlDependencies = {
  function extractWorkflowYamlDependencies (line 11) | function extractWorkflowYamlDependencies(

FILE: keep-ui/entities/workflows/lib/generateWorkflowYamlJsonSchema.ts
  function generateWorkflowYamlJsonSchema (line 40) | function generateWorkflowYamlJsonSchema(zodSchema: ZodSchema) {

FILE: keep-ui/entities/workflows/lib/getHumanReadableInterval.ts
  function getHumanReadableInterval (line 3) | function getHumanReadableInterval(interval: number | string) {

FILE: keep-ui/entities/workflows/lib/getTriggerDescription.ts
  function getTriggerDescription (line 5) | function getTriggerDescription(trigger: Trigger) {
  function getTriggerDescriptionFromStep (line 30) | function getTriggerDescriptionFromStep(trigger: V2StepTrigger) {

FILE: keep-ui/entities/workflows/lib/mustache.ts
  constant MUSTACHE_REGEX (line 1) | const MUSTACHE_REGEX = /\{\{\s*(.*?)\s*\}\}/g;
  constant ALLOWED_MUSTACHE_VARIABLE_REGEX (line 2) | const ALLOWED_MUSTACHE_VARIABLE_REGEX = /^[a-zA-Z0-9._-\s]+$/;
  function extractMustacheVariables (line 10) | function extractMustacheVariables(yamlString: string): string[] {

FILE: keep-ui/entities/workflows/lib/parser.ts
  type StepOrActionWithType (line 44) | type StepOrActionWithType = YamlStepOrAction & { type: "step" | "action" };
  function getV2StepOrV2Action (line 46) | function getV2StepOrV2Action(
  function getV2Foreach (line 75) | function getV2Foreach(
  function getV2Condition (line 97) | function getV2Condition(
  function getWorkflowDefinition (line 137) | function getWorkflowDefinition(
  function parseWorkflow (line 178) | function parseWorkflow(
  function getWithParams (line 294) | function getWithParams(
  function getYamlConditionFromStep (line 322) | function getYamlConditionFromStep(
  function getActionsFromCondition (line 341) | function getActionsFromCondition(
  function getYamlStepFromStep (line 394) | function getYamlStepFromStep(
  function getYamlActionFromAction (line 431) | function getYamlActionFromAction(
  function getYamlWorkflowDefinition (line 471) | function getYamlWorkflowDefinition(
  function wrapDefinitionV2 (line 597) | function wrapDefinitionV2({
  function extractWorkflowInputs (line 611) | function extractWorkflowInputs(workflowYaml: string): WorkflowInput[] {

FILE: keep-ui/entities/workflows/lib/ui-utils.tsx
  function getTriggerIcon (line 27) | function getTriggerIcon(triggered_by: string) {
  function extractTriggerValue (line 42) | function extractTriggerValue(triggered_by: string | undefined): string {
  function extractTriggerType (line 61) | function extractTriggerType(
  function extractTriggerDetails (line 81) | function extractTriggerDetails(
  type TriggerDetails (line 115) | type TriggerDetails = {
  function extractTriggerDetailsV2 (line 120) | function extractTriggerDetailsV2(

FILE: keep-ui/entities/workflows/lib/use-query-workflow-template.ts
  function useQueryWorkflowTemplate (line 7) | function useQueryWorkflowTemplate(

FILE: keep-ui/entities/workflows/lib/useWorkflowJsonSchema.ts
  function useWorkflowJsonSchema (line 7) | function useWorkflowJsonSchema() {

FILE: keep-ui/entities/workflows/lib/useWorkflowZodSchema.ts
  function useWorkflowZodSchema (line 8) | function useWorkflowZodSchema() {

FILE: keep-ui/entities/workflows/lib/validate-definition.ts
  type ValidationResult (line 6) | type ValidationResult = [string, string];
  type ValidationError (line 7) | type ValidationError = [string, "error" | "warning" | "info"];
  function validateGlobalPure (line 15) | function validateGlobalPure(definition: Definition): ValidationResult[] {
  function validateProviderConfig (line 89) | function validateProviderConfig(
  function validateStepPure (line 128) | function validateStepPure(

FILE: keep-ui/entities/workflows/lib/validate-mustache-ui-builder.ts
  type V2StepWithParentId (line 10) | type V2StepWithParentId = V2Step & { parentId?: string };
  function flattenSequence (line 175) | function flattenSequence(

FILE: keep-ui/entities/workflows/lib/validate-mustache-yaml.ts
  type Optional (line 12) | type Optional<T, K extends keyof T> = Omit<T, K> & Partial<T>;

FILE: keep-ui/entities/workflows/lib/yaml-utils.ts
  constant YAML_STRINGIFY_OPTIONS (line 17) | const YAML_STRINGIFY_OPTIONS = {
  function getOrderedWorkflowYamlString (line 22) | function getOrderedWorkflowYamlString(yamlString: string) {
  function orderDocument (line 43) | function orderDocument(doc: Document) {
  function getOrderedWorkflowYamlStringFromJSON (line 194) | function getOrderedWorkflowYamlStringFromJSON(json: any) {
  function parseWorkflowYamlStringToJSON (line 200) | function parseWorkflowYamlStringToJSON(yamlString: string) {
  function parseWorkflowYamlToJSON (line 208) | function parseWorkflowYamlToJSON<T extends z.ZodSchema>(
  function getCurrentPath (line 222) | function getCurrentPath(document: Document, absolutePosition: number) {
  function getBodyFromStringOrDefinitionOrObject (line 256) | function getBodyFromStringOrDefinitionOrObject(

FILE: keep-ui/entities/workflows/model/types.ts
  type IncidentEvent (line 21) | type IncidentEvent = z.infer<typeof IncidentEventEnum>;
  type V2StepTrigger (line 22) | type V2StepTrigger = z.infer<typeof V2StepTriggerSchema>;
  type TriggerType (line 23) | type TriggerType = V2StepTrigger["type"];
  type V2ActionStep (line 24) | type V2ActionStep = z.infer<typeof V2ActionSchema>;
  type V2StepStep (line 25) | type V2StepStep = z.infer<typeof V2StepStepSchema>;
  type V2ActionOrStep (line 26) | type V2ActionOrStep = z.infer<typeof V2ActionOrStepSchema>;
  type V2StepConditionAssert (line 27) | type V2StepConditionAssert = z.infer<typeof V2StepConditionAssertSchema>;
  type V2StepConditionThreshold (line 28) | type V2StepConditionThreshold = z.infer<
  type V2StepCondition (line 31) | type V2StepCondition = z.infer<typeof V2StepConditionSchema>;
  type V2StepForeach (line 32) | type V2StepForeach = z.infer<typeof V2StepForeachSchema>;
  type V2StepTemplate (line 33) | type V2StepTemplate = z.infer<typeof V2StepTemplateSchema>;
  type V2StartStep (line 35) | type V2StartStep = {
  type V2EndStep (line 43) | type V2EndStep = {
  type TriggerStartLabelStep (line 51) | type TriggerStartLabelStep = {
  type TriggerEndLabelStep (line 58) | type TriggerEndLabelStep = {
  type V2Step (line 67) | type V2Step = z.infer<typeof V2StepSchema>;
  type WorkflowMetadata (line 68) | type WorkflowMetadata = Pick<Workflow, "name" | "description">;
  type V2Properties (line 69) | type V2Properties = Record<string, any>;
  type WorkflowProperties (line 70) | type WorkflowProperties = z.infer<typeof WorkflowPropertiesSchema>;
  type Definition (line 72) | type Definition = {
  type DefinitionV2 (line 78) | type DefinitionV2 = {
  type V2StepTempNode (line 86) | type V2StepTempNode = V2Step & {
  type UIProps (line 91) | type UIProps = {
  type V2StepUI (line 100) | type V2StepUI = V2Step & UIProps;
  type V2StepTriggerUI (line 101) | type V2StepTriggerUI = V2StepTrigger & UIProps;
  type EmptyNode (line 103) | type EmptyNode = {
  type ConditionAssertEndNodeData (line 112) | type ConditionAssertEndNodeData = {
  type ConditionThresholdEndNodeData (line 120) | type ConditionThresholdEndNodeData = {
  type NodeData (line 129) | type NodeData = (
  type NodeStepMeta (line 139) | type NodeStepMeta = { id: string; label?: string };
  type FlowNode (line 140) | type FlowNode = Node & {
  type StoreGet (line 154) | type StoreGet = () => WorkflowState;
  type StoreSet (line 155) | type StoreSet = (
  type ToolboxConfiguration (line 162) | type ToolboxConfiguration = {
  type InitializationConfiguration (line 175) | type InitializationConfiguration = {
  type WorkflowStateValues (line 181) | interface WorkflowStateValues {
  type WorkflowState (line 215) | interface WorkflowState extends WorkflowStateValues {

FILE: keep-ui/entities/workflows/model/useWorkflowActions.ts
  type DeleteOptions (line 10) | type DeleteOptions = {
  type UseWorkflowActionsReturn (line 14) | type UseWorkflowActionsReturn = {
  type CreateOrUpdateWorkflowResponse (line 29) | type CreateOrUpdateWorkflowResponse = {
  function useWorkflowActions (line 35) | function useWorkflowActions(): UseWorkflowActionsReturn {

FILE: keep-ui/entities/workflows/model/useWorkflowDetail.ts
  function useWorkflowDetail (line 6) | function useWorkflowDetail(

FILE: keep-ui/entities/workflows/model/useWorkflowRevalidation.ts
  function useWorkflowRevalidation (line 9) | function useWorkflowRevalidation() {

FILE: keep-ui/entities/workflows/model/useWorkflowRevisions.ts
  function useWorkflowRevisions (line 6) | function useWorkflowRevisions(

FILE: keep-ui/entities/workflows/model/useWorkflowsV2.ts
  constant DEFAULT_WORKFLOWS_PAGINATION (line 8) | const DEFAULT_WORKFLOWS_PAGINATION = {
  constant DEFAULT_WORKFLOWS_QUERY (line 13) | const DEFAULT_WORKFLOWS_QUERY = {
  type WorkflowTemplatesQuery (line 20) | interface WorkflowTemplatesQuery {
  type WorkflowsQuery (line 26) | interface WorkflowsQuery {
  function useWorkflowsV2 (line 36) | function useWorkflowsV2(

FILE: keep-ui/entities/workflows/model/workflow-store.ts
  class KeepWorkflowStoreError (line 59) | class KeepWorkflowStoreError extends Error {
    method constructor (line 60) | constructor(message: string) {
  constant PROTECTED_NODE_IDS (line 65) | const PROTECTED_NODE_IDS = ["start", "end", "trigger_start", "trigger_en...
  function addNodeBetween (line 78) | function addNodeBetween(
  function onLayout (line 794) | function onLayout(
  function initializeWorkflow (line 835) | function initializeWorkflow(
  function useUIBuilderUnsavedChanges (line 911) | function useUIBuilderUnsavedChanges() {

FILE: keep-ui/entities/workflows/model/workflow-yaml-editor-store.ts
  type WorkflowYAMLEditorStateValues (line 5) | type WorkflowYAMLEditorStateValues = {
  type WorkflowYAMLEditorState (line 19) | type WorkflowYAMLEditorState = WorkflowYAMLEditorStateValues & {

FILE: keep-ui/entities/workflows/model/yaml.schema.ts
  type ProviderMetadataForValidation (line 14) | type ProviderMetadataForValidation = Pick<
  function getYamlProviderSchema (line 117) | function getYamlProviderSchema(
  function getYamlWorkflowDefinitionSchema (line 245) | function getYamlWorkflowDefinitionSchema(

FILE: keep-ui/entities/workflows/model/yaml.types.ts
  type YamlStepOrAction (line 11) | type YamlStepOrAction = z.infer<typeof YamlStepOrActionSchema>;
  type YamlThresholdCondition (line 12) | type YamlThresholdCondition = z.infer<
  type WorkflowInput (line 16) | type WorkflowInput = z.infer<typeof WorkflowInputSchema>;
  type WorkflowInputType (line 17) | type WorkflowInputType = WorkflowInput["type"];
  type WorkflowStrategy (line 19) | type WorkflowStrategy = z.infer<typeof WorkflowStrategySchema>;
  type YamlAssertCondition (line 21) | type YamlAssertCondition = z.infer<typeof YamlAssertConditionSchema>;
  type YamlWorkflowDefinition (line 23) | type YamlWorkflowDefinition = z.infer<

FILE: keep-ui/entities/workflows/ui/NodeTriggerIcon.tsx
  function NodeTriggerIcon (line 9) | function NodeTriggerIcon({ nodeData }: { nodeData: NodeData }) {

FILE: keep-ui/entities/workflows/ui/TriggerIcon.tsx
  function TriggerIcon (line 10) | function TriggerIcon({

FILE: keep-ui/entities/workflows/ui/WorkflowAlertIncidentDependenciesForm.tsx
  type Field (line 42) | interface Field {
  type Payload (line 47) | type Payload = Record<string, any>;
  type WorkflowAlertDependenciesFormProps (line 49) | interface WorkflowAlertDependenciesFormProps {
  type WorkflowIncidentDependenciesFormProps (line 58) | type WorkflowIncidentDependenciesFormProps = {
  type WorkflowDependenciesFormProps (line 67) | type WorkflowDependenciesFormProps =
  function WorkflowAlertIncidentDependenciesForm (line 71) | function WorkflowAlertIncidentDependenciesForm({

FILE: keep-ui/entities/workflows/ui/WorkflowInputFields.tsx
  type WorkflowInputFieldsProps (line 3) | interface WorkflowInputFieldsProps {
  function WorkflowInputFields (line 9) | function WorkflowInputFields({
  function areRequiredInputsFilled (line 186) | function areRequiredInputsFilled(

FILE: keep-ui/entities/workflows/ui/WorkflowPermissionsBadge.tsx
  function WorkflowPermissionsBadge (line 5) | function WorkflowPermissionsBadge({

FILE: keep-ui/entities/workflows/ui/WorkflowTriggerBadge.tsx
  function WorkflowTriggerBadge (line 7) | function WorkflowTriggerBadge({

FILE: keep-ui/errors.ts
  class AuthenticationError (line 3) | class AuthenticationError extends AuthError {
    method constructor (line 5) | constructor(message: string) {

FILE: keep-ui/features/alerts/alert-assign-ticket/ui/alert-assign-ticket-modal.tsx
  type AlertAssignTicketModalProps (line 13) | interface AlertAssignTicketModalProps {
  type OptionType (line 19) | interface OptionType {
  type FormData (line 28) | interface FormData {

FILE: keep-ui/features/alerts/alert-associate-to-incident/ui/alert-associate-incident-modal.tsx
  type AlertAssociateIncidentModalProps (line 17) | interface AlertAssociateIncidentModalProps {

FILE: keep-ui/features/alerts/alert-call-provider-method/ui/alert-method-modal.tsx
  type AlertMethodModalProps (line 29) | interface AlertMethodModalProps {
  function AlertMethodModal (line 34) | function AlertMethodModal({

FILE: keep-ui/features/alerts/alert-call-provider-method/ui/alert-method-results-table.tsx
  function AlertMethodResultsTable (line 10) | function AlertMethodResultsTable({

FILE: keep-ui/features/alerts/alert-change-status/ui/alert-change-status-modal.tsx
  type Props (line 31) | interface Props {
  function AlertChangeStatusModal (line 37) | function AlertChangeStatusModal({

FILE: keep-ui/features/alerts/alert-create-incident-ai/ui/alert-create-incident-ai-card.tsx
  type IncidentCardProps (line 29) | interface IncidentCardProps {
  type EditableField (line 35) | interface EditableField {
  type DraggableAlertRowProps (line 52) | interface DraggableAlertRowProps {

FILE: keep-ui/features/alerts/alert-create-incident-ai/ui/alert-create-incident-ai-modal.tsx
  type CreateIncidentWithAIModalProps (line 26) | interface CreateIncidentWithAIModalProps {
  type IncidentChange (line 32) | interface IncidentChange {
  type IncidentSuggestion (line 37) | interface IncidentSuggestion {
  function deepCopy (line 42) | function deepCopy<T>(obj: T): T {
  function handleSuccess (line 91) | function handleSuccess(data: IncidentSuggestion) {

FILE: keep-ui/features/alerts/alert-detail-sidebar/lib/alertSidebarFields.tsx
  function getNestedValue (line 18) | function getNestedValue(obj: any, path: string): any {
  function formatFieldName (line 45) | function formatFieldName(fieldPath: string): string {
  type AlertSidebarFieldName (line 58) | type AlertSidebarFieldName =
  type AlertSidebarFieldRendererProps (line 69) | interface AlertSidebarFieldRendererProps {
  type AlertSidebarFieldConfig (line 77) | interface AlertSidebarFieldConfig {
  function getEnabledFields (line 240) | function getEnabledFields(
  function getCustomFields (line 251) | function getCustomFields(configuredFields: string[]): string[] {
  function renderCustomField (line 260) | function renderCustomField(

FILE: keep-ui/features/alerts/alert-detail-sidebar/ui/alert-sidebar-incidents.tsx
  type CollapsibleIncidentsListProps (line 4) | interface CollapsibleIncidentsListProps {

FILE: keep-ui/features/alerts/alert-detail-sidebar/ui/alert-sidebar.tsx
  type AlertSidebarProps (line 32) | type AlertSidebarProps = {

FILE: keep-ui/features/alerts/alert-detail-sidebar/ui/alert-timeline.tsx
  type AlertTimelineProps (line 16) | type AlertTimelineProps = {

FILE: keep-ui/features/alerts/alert-error-event-process/ui/alert-error-event-modal.tsx
  type ErrorAlert (line 17) | interface ErrorAlert {
  type AlertErrorEventModalProps (line 25) | interface AlertErrorEventModalProps {

FILE: keep-ui/features/alerts/alert-history/ui/alert-history-charts.tsx
  type Props (line 6) | interface Props {
  function AlertHistoryCharts (line 26) | function AlertHistoryCharts({

FILE: keep-ui/features/alerts/alert-history/ui/alert-history-modal.tsx
  type AlertHistoryPanelProps (line 14) | interface AlertHistoryPanelProps {
  type Props (line 121) | interface Props {
  function AlertHistoryModal (line 127) | function AlertHistoryModal({ alerts, presetName, onClose }: Props) {

FILE: keep-ui/features/alerts/alert-menu/ui/alert-menu.tsx
  type Props (line 51) | interface Props {
  type MenuItem (line 64) | interface MenuItem {
  function AlertMenu (line 74) | function AlertMenu({

FILE: keep-ui/features/alerts/alert-note/ui/alert-note-modal.tsx
  type AlertNoteModalProps (line 14) | interface AlertNoteModalProps {

FILE: keep-ui/features/alerts/change-alert-table-theme/ui/AlertTableThemeSelection.tsx
  type ThemeName (line 43) | type ThemeName = keyof typeof predefinedThemes;

FILE: keep-ui/features/alerts/dismiss-alert/ui/alert-dismiss-modal.tsx
  type Props (line 30) | interface Props {
  function AlertDismissModal (line 36) | function AlertDismissModal({

FILE: keep-ui/features/alerts/enrich-alert/ui/EnrichAlertSidePanel.tsx
  type EnrichAlertModalProps (line 9) | interface EnrichAlertModalProps {

FILE: keep-ui/features/alerts/severity-mapping/ui/SeverityMappingFacet.tsx
  type SeverityMappingFacetProps (line 6) | interface SeverityMappingFacetProps {
  function SeverityMappingFacet (line 11) | function SeverityMappingFacet({

FILE: keep-ui/features/alerts/severity-mapping/ui/SeverityMappingSelection.tsx
  type MappingEntry (line 9) | interface MappingEntry {
  constant DEFAULT_COLOR (line 14) | const DEFAULT_COLOR = "#3b82f6";
  function SeverityMappingSelection (line 16) | function SeverityMappingSelection({

FILE: keep-ui/features/alerts/simulate-alert/ui/alert-push-alert-to-server-modal.tsx
  type PushAlertToServerModalProps (line 19) | interface PushAlertToServerModalProps {
  type AlertSource (line 25) | interface AlertSource {

FILE: keep-ui/features/alerts/view-raw-alert/ui/ViewAlertModal.tsx
  type ViewAlertModalProps (line 15) | interface ViewAlertModalProps {
  constant READ_ONLY_FIELDS (line 22) | const READ_ONLY_FIELDS = [
  constant ENUM_FIELDS (line 43) | const ENUM_FIELDS: Record<string, string[]> = {
  type ValidationError (line 49) | interface ValidationError {

FILE: keep-ui/features/cel-input/cel-input.tsx
  type CelInputProps (line 8) | interface CelInputProps {

FILE: keep-ui/features/cel-input/use-cel-state.ts
  function useCelState (line 6) | function useCelState({

FILE: keep-ui/features/filter/add-facet-modal-with-suggestions.tsx
  type AddFacetModalWithSuggestions (line 10) | interface AddFacetModalWithSuggestions {
  function isSubmitEnabled (line 40) | function isSubmitEnabled(): boolean {

FILE: keep-ui/features/filter/add-facet-modal.tsx
  type AddFacetModalProps (line 7) | interface AddFacetModalProps {
  function isSubmitEnabled (line 35) | function isSubmitEnabled(): boolean {

FILE: keep-ui/features/filter/api.ts
  type InitialFacetsData (line 4) | interface InitialFacetsData {
  function getInitialFacets (line 15) | async function getInitialFacets(
  function getInitialFacetsData (line 28) | async function getInitialFacetsData(

FILE: keep-ui/features/filter/facet-panel-server-side.tsx
  type FacetsPanelProps (line 16) | interface FacetsPanelProps {

FILE: keep-ui/features/filter/facet-value.tsx
  type FacetValueProps (line 6) | interface FacetValueProps {

FILE: keep-ui/features/filter/facet.tsx
  type FacetProps (line 13) | interface FacetProps {
  function getSelectedValues (line 69) | function getSelectedValues(): string[] {
  function checkIfOptionExclusievlySelected (line 151) | function checkIfOptionExclusievlySelected(optionValue: string): boolean {
  function renderSkeleton (line 163) | function renderSkeleton(key: string) {
  function renderFacetValue (line 172) | function renderFacetValue(facetOption: FacetOptionDto, index: number) {
  function renderBody (line 207) | function renderBody() {

FILE: keep-ui/features/filter/facets-panel.tsx
  type FacetsPanelProps (line 15) | interface FacetsPanelProps {

FILE: keep-ui/features/filter/hooks.tsx
  type UseFacetActionsValue (line 15) | type UseFacetActionsValue = {

FILE: keep-ui/features/filter/models.tsx
  type FacetState (line 3) | type FacetState = Record<string, any | null>;
  type FacetConfig (line 5) | interface FacetConfig {
  type FacetsConfig (line 15) | interface FacetsConfig {
  type FacetOptionDto (line 19) | interface FacetOptionDto {
  type FacetOptionsDict (line 25) | type FacetOptionsDict = { [facetId: string]: FacetOptionDto[] };
  type FacetOptionsQuery (line 26) | type FacetOptionsQuery = {
  type FacetOptionsQueries (line 30) | type FacetOptionsQueries = { [facet_id: string]: string };
  type FacetDto (line 32) | interface FacetDto {
  type CreateFacetDto (line 40) | interface CreateFacetDto {

FILE: keep-ui/features/filter/pagination.tsx
  type PaginationState (line 14) | interface PaginationState {
  type OptionType (line 19) | interface OptionType {
  type Props (line 34) | interface Props {
  function Pagination (line 44) | function Pagination({

FILE: keep-ui/features/filter/search-input.tsx
  type SearchInputProps (line 4) | interface SearchInputProps {

FILE: keep-ui/features/filter/store/create-facets-store.ts
  type FacetsPanelState (line 6) | type FacetsPanelState = {
  method toggleFacetOption (line 99) | toggleFacetOption(facetId, optionValue) {
  method selectOneFacetOption (line 135) | selectOneFacetOption(facetId, optionValue) {
  method selectAllFacetOptions (line 150) | selectAllFacetOptions(facetId) {

FILE: keep-ui/features/filter/store/use-facets-config.tsx
  function useFacetsConfig (line 6) | function useFacetsConfig(

FILE: keep-ui/features/filter/store/use-facets-loading-state-handler.ts
  function useFacetsLoadingStateHandler (line 5) | function useFacetsLoadingStateHandler(

FILE: keep-ui/features/filter/store/use-initial-state-handler.ts
  function useInitialStateHandler (line 7) | function useInitialStateHandler(store: StoreApi<FacetsPanelState>) {

FILE: keep-ui/features/filter/store/use-queries-handler.ts
  function buildStringFacetCel (line 7) | function buildStringFacetCel(
  function buildFacetsCelState (line 29) | function buildFacetsCelState(
  function useQueriesHandler (line 47) | function useQueriesHandler(store: StoreApi<FacetsPanelState>) {

FILE: keep-ui/features/filter/store/use-query-params/split-facet-values.ts
  function splitFacetValues (line 18) | function splitFacetValues(input: string) {

FILE: keep-ui/features/filter/store/use-query-params/use-query-params.ts
  function areFacetQueryParamsEqual (line 14) | function areFacetQueryParamsEqual(
  function buildFacetQueryParams (line 35) | function buildFacetQueryParams(
  function replaceQueryParams (line 66) | function replaceQueryParams(searchParams: URLSearchParams): void {
  function useQueryParams (line 74) | function useQueryParams(store: StoreApi<FacetsPanelState>) {

FILE: keep-ui/features/filter/store/use-store.tsx
  function useNewFacetStore (line 15) | function useNewFacetStore(facetsConfig: FacetsConfig | undefined) {
  function useExistingFacetsPanelStore (line 49) | function useExistingFacetsPanelStore<T>(

FILE: keep-ui/features/filter/store/utils.ts
  function valueToString (line 1) | function valueToString(value: any): string {
  function stringToValue (line 20) | function stringToValue(str: string): any {
  function toFacetState (line 48) | function toFacetState(values: string[]): Record<string, boolean> {

FILE: keep-ui/features/incidents/change-incident-severity/ui/incident-change-severity-select.tsx
  type Props (line 6) | type Props = {
  function IncidentChangeSeveritySelect (line 13) | function IncidentChangeSeveritySelect({

FILE: keep-ui/features/incidents/change-incident-severity/ui/incident-severity-select.tsx
  type Props (line 30) | type Props = {
  function IncidentSeveritySelect (line 36) | function IncidentSeveritySelect({ value, onChange, className }: Props) {

FILE: keep-ui/features/incidents/change-incident-status/ui/incident-change-status-select.tsx
  type Props (line 29) | type Props = {
  function IncidentChangeStatusSelect (line 36) | function IncidentChangeStatusSelect({

FILE: keep-ui/features/incidents/create-or-update-incident/ui/create-or-update-incident-form.tsx
  type Props (line 27) | interface Props {
  function CreateOrUpdateIncidentForm (line 33) | function CreateOrUpdateIncidentForm({

FILE: keep-ui/features/incidents/incident-list/ui/incident-dropdown-menu.tsx
  type Props (line 7) | interface Props {
  function IncidentDropdownMenu (line 13) | function IncidentDropdownMenu({

FILE: keep-ui/features/incidents/incident-list/ui/incident-list-error.tsx
  type IncidentListErrorProps (line 4) | interface IncidentListErrorProps {

FILE: keep-ui/features/incidents/incident-list/ui/incident-list-placeholder.tsx
  type Props (line 4) | interface Props {

FILE: keep-ui/features/incidents/incident-list/ui/incident-list.tsx
  function IncidentList (line 61) | function IncidentList({

FILE: keep-ui/features/incidents/incident-list/ui/incident-table-component.tsx
  type Props (line 17) | interface Props {
  type SortableHeaderCellProps (line 21) | interface SortableHeaderCellProps {

FILE: keep-ui/features/incidents/incident-list/ui/incident-table-filters-context.tsx
  type IIncidentFilterContext (line 17) | interface IIncidentFilterContext {

FILE: keep-ui/features/incidents/incident-list/ui/incidents-not-found.tsx
  type Props (line 8) | interface Props {

FILE: keep-ui/features/incidents/incident-list/ui/incidents-report/generate-report-modal.tsx
  type GenerateReportModalProps (line 11) | interface GenerateReportModalProps {

FILE: keep-ui/features/incidents/incident-list/ui/incidents-report/incident-severity-metric.tsx
  type IncidentSeverityMetricProps (line 9) | interface IncidentSeverityMetricProps {
  function formatIncidentsCount (line 42) | function formatIncidentsCount(count: number): string {

FILE: keep-ui/features/incidents/incident-list/ui/incidents-report/incidents-report.tsx
  type IncidentsReportProps (line 6) | interface IncidentsReportProps {
  function convertSeconds (line 13) | function convertSeconds(secondsValue: number): string {
  function formatIncidentsCount (line 47) | function formatIncidentsCount(count: number): string {
  function renderTimeMetric (line 51) | function renderTimeMetric(
  function renderMainReasons (line 65) | function renderMainReasons(): React.JSX.Element {
  function renderAffectedServices (line 82) | function renderAffectedServices(): React.JSX.Element {
  function renderRecurringIncidents (line 99) | function renderRecurringIncidents(): React.JSX.Element {
  function renderTimeMetrics (line 116) | function renderTimeMetrics(): React.JSX.Element {

FILE: keep-ui/features/incidents/incident-list/ui/incidents-report/models.ts
  type IncidentMetrics (line 1) | interface IncidentMetrics {
  type IncidentDurations (line 8) | interface IncidentDurations {
  type Incident (line 15) | interface Incident {
  type ReoccurringIncident (line 20) | interface ReoccurringIncident extends Incident {
  type SeverityMetrics (line 24) | interface SeverityMetrics {
  type IncidentData (line 28) | interface IncidentData {

FILE: keep-ui/features/incidents/incident-list/ui/incidents-report/pie-chart.tsx
  type PieChartProps (line 4) | interface PieChartProps {

FILE: keep-ui/features/incidents/incident-list/ui/incidents-table.tsx
  function SelectedRowActions (line 39) | function SelectedRowActions({
  type Props (line 96) | interface Props {
  function IncidentsTable (line 106) | function IncidentsTable({

FILE: keep-ui/features/incidents/incident-list/ui/useIncidentsTableData.tsx
  type IncidentsTableDataQuery (line 16) | interface IncidentsTableDataQuery {
  function updateIncidentsCelDateRange (line 83) | function updateIncidentsCelDateRange() {

FILE: keep-ui/features/incidents/merge-incidents/ui/merge-incidents-modal.tsx
  type Props (line 8) | interface Props {
  function MergeIncidentsModal (line 14) | function MergeIncidentsModal({

FILE: keep-ui/features/incidents/same-incidents-in-the-past/ui/change-same-incident-in-the-past-form.tsx
  type ChangeSameIncidentInThePastFormProps (line 11) | interface ChangeSameIncidentInThePastFormProps {
  function ChangeSameIncidentInThePastForm (line 17) | function ChangeSameIncidentInThePastForm({

FILE: keep-ui/features/incidents/same-incidents-in-the-past/ui/following-incidents.tsx
  function FollowingIncident (line 13) | function FollowingIncident({ incidentId }: { incidentId: string }) {
  function FollowingIncidents (line 32) | function FollowingIncidents({ incident }: { incident: IncidentDto }) {

FILE: keep-ui/features/incidents/same-incidents-in-the-past/ui/same-incident-field.tsx
  function SameIncidentField (line 12) | function SameIncidentField({ incident }: { incident: IncidentDto }) {

FILE: keep-ui/features/incidents/split-incident-alerts/ui/split-incident-alerts-modal.tsx
  type Props (line 14) | interface Props {
  function SplitIncidentAlertsModal (line 21) | function SplitIncidentAlertsModal({

FILE: keep-ui/features/keyboard-shortcuts/useIsShiftKeyHeld.ts
  function useIsShiftKeyHeld (line 3) | function useIsShiftKeyHeld() {

FILE: keep-ui/features/presets/create-or-update-preset/ui/alerts-count-badge.tsx
  type AlertsCountBadgeProps (line 5) | interface AlertsCountBadgeProps {

FILE: keep-ui/features/presets/create-or-update-preset/ui/create-or-update-preset-form.tsx
  type TagOption (line 20) | interface TagOption {
  type CreateOrUpdatePresetFormProps (line 25) | type CreateOrUpdatePresetFormProps = {
  function CreateOrUpdatePresetForm (line 41) | function CreateOrUpdatePresetForm({

FILE: keep-ui/features/presets/create-or-update-preset/ui/preset-controls.tsx
  type PresetControlsProps (line 5) | interface PresetControlsProps {

FILE: keep-ui/features/presets/custom-preset-links/ui/CustomPresetAlertLinks.tsx
  type AlertPresetLinkProps (line 30) | type AlertPresetLinkProps = {
  type CustomPresetAlertLinksProps (line 137) | type CustomPresetAlertLinksProps = {

FILE: keep-ui/features/presets/custom-preset-links/ui/PresetsNoise.tsx
  type PresetsNoiseProps (line 11) | interface PresetsNoiseProps {

FILE: keep-ui/features/presets/presets-manager/ui/alert-preset-manager.tsx
  type Props (line 19) | interface Props {
  function AlertPresetManager (line 30) | function AlertPresetManager({

FILE: keep-ui/features/presets/presets-manager/ui/alerts-rules-builder.tsx
  type CustomMenuListProps (line 60) | interface CustomMenuListProps
  type AlertsRulesBuilderProps (line 134) | type AlertsRulesBuilderProps = {
  constant SQL_QUERY_PLACEHOLDER (line 150) | const SQL_QUERY_PLACEHOLDER = `SELECT *
  function handleClickOutside (line 250) | function handleClickOutside(event: any) {
  function getSaveFilterTooltipText (line 349) | function getSaveFilterTooltipText(): string {

FILE: keep-ui/features/workflow-execution-results/lib/logs-utils.ts
  function getLogLineStatus (line 3) | function getLogLineStatus(log: LogEntry) {
  function getStepStatus (line 13) | function getStepStatus(

FILE: keep-ui/features/workflow-execution-results/ui/WorkflowExecutionError.tsx
  function WorkflowExecutionError (line 11) | function WorkflowExecutionError({

FILE: keep-ui/features/workflow-execution-results/ui/WorkflowExecutionLogs.tsx
  function getStepIcon (line 22) | function getStepIcon(status: string) {
  type LogGroup (line 35) | type LogGroup = {
  function formatStepDuration (line 47) | function formatStepDuration(startTime: Date | null, endTime: Date | null) {
  function getAccordionHeaderClassName (line 60) | function getAccordionHeaderClassName(
  function getChevronIconClassName (line 99) | function getChevronIconClassName(status: string | null) {
  function getLogLineClassName (line 112) | function getLogLineClassName(log: LogEntry) {
  function LogGroupAccordion (line 121) | function LogGroupAccordion({
  function WorkflowExecutionLogs (line 194) | function WorkflowExecutionLogs({

FILE: keep-ui/features/workflow-execution-results/ui/WorkflowExecutionResults.tsx
  constant WAIT_AFTER_STATUS_CHANGED (line 27) | const WAIT_AFTER_STATUS_CHANGED = 2000;
  type WorkflowResultsProps (line 38) | interface WorkflowResultsProps {
  function WorkflowExecutionResults (line 49) | function WorkflowExecutionResults({
  function WorkflowExecutionResultsInternal (line 166) | function WorkflowExecutionResultsInternal({

FILE: keep-ui/features/workflows/ai-assistant/lib/constants.ts
  constant GENERAL_INSTRUCTIONS (line 1) | const GENERAL_INSTRUCTIONS = `

FILE: keep-ui/features/workflows/ai-assistant/lib/utils.ts
  function getYamlFromStep (line 14) | function getYamlFromStep(step: V2Step | V2StepTrigger) {
  function getWorkflowSummaryForCopilot (line 36) | function getWorkflowSummaryForCopilot(nodes: FlowNode[], edges: Edge[]) {
  function getErrorMessage (line 52) | function getErrorMessage(e: unknown, defaultMessage?: string) {

FILE: keep-ui/features/workflows/ai-assistant/ui/AddStepUI.tsx
  type AddStepUIPropsCommon (line 9) | type AddStepUIPropsCommon = {
  type AddStepUIPropsComplete (line 14) | type AddStepUIPropsComplete = AddStepUIPropsCommon & {
  type AddStepUIPropsExecuting (line 20) | type AddStepUIPropsExecuting = AddStepUIPropsCommon & {
  type AddStepUIProps (line 26) | type AddStepUIProps = AddStepUIPropsComplete | AddStepUIPropsExecuting;

FILE: keep-ui/features/workflows/ai-assistant/ui/AddTriggerUI.tsx
  type AddTriggerUIPropsCommon (line 11) | type AddTriggerUIPropsCommon = {
  type AddTriggerUIPropsComplete (line 15) | type AddTriggerUIPropsComplete = AddTriggerUIPropsCommon & {
  type AddTriggerUIPropsExecuting (line 21) | type AddTriggerUIPropsExecuting = AddTriggerUIPropsCommon & {
  type AddTriggerUIProps (line 27) | type AddTriggerUIProps = AddTriggerUIPropsComplete | AddTriggerUIPropsEx...

FILE: keep-ui/features/workflows/ai-assistant/ui/StepPreview.tsx
  function getStepIconUrl (line 12) | function getStepIconUrl(data: V2Step | V2StepTrigger) {

FILE: keep-ui/features/workflows/ai-assistant/ui/SuggestionStatus.tsx
  type SuggestionStatus (line 7) | type SuggestionStatus = "complete" | "error" | "declined";
  type SuggestionResult (line 8) | type SuggestionResult = {

FILE: keep-ui/features/workflows/ai-assistant/ui/WorkflowBuilderChat.tsx
  type WorkflowBuilderChatProps (line 49) | interface WorkflowBuilderChatProps {
  function WorkflowBuilderChat (line 54) | function WorkflowBuilderChat({

FILE: keep-ui/features/workflows/ai-assistant/ui/WorkflowBuilderChatSafe.tsx
  type WorkflowBuilderChatSafeProps (line 13) | type WorkflowBuilderChatSafeProps = Omit<
  function WorkflowBuilderChatSafe (line 20) | function WorkflowBuilderChatSafe({

FILE: keep-ui/features/workflows/builder/lib/utils.tsx
  function getToolboxConfiguration (line 110) | function getToolboxConfiguration(
  function edgeCanHaveAddButton (line 185) | function edgeCanHaveAddButton(source: string, target: string) {
  function canAddTriggerBeforeEdge (line 198) | function canAddTriggerBeforeEdge(source: string, target: string) {
  function canAddStepBeforeEdge (line 202) | function canAddStepBeforeEdge(source: string, target: string) {
  function canAddConditionBeforeEdge (line 210) | function canAddConditionBeforeEdge(source: string, target: string) {
  function canAddForeachBeforeEdge (line 214) | function canAddForeachBeforeEdge(source: string, target: string) {

FILE: keep-ui/features/workflows/builder/ui/Editor/EditorField.tsx
  function EditorField (line 5) | function EditorField({

FILE: keep-ui/features/workflows/builder/ui/Editor/StepEditor.tsx
  function EditorLayout (line 45) | function EditorLayout({
  function KeyValueListField (line 57) | function KeyValueListField({
  type KeepEditorProps (line 123) | interface KeepEditorProps {
  function InstallProviderButton (line 133) | function InstallProviderButton({
  function KeepSetupProviderEditor (line 213) | function KeepSetupProviderEditor({
  function KeepStepEditor (line 374) | function KeepStepEditor({
  function KeepThresholdConditionEditor (line 520) | function KeepThresholdConditionEditor({
  function KeepAssertConditionEditor (line 571) | function KeepAssertConditionEditor({
  function KeepForeachEditor (line 597) | function KeepForeachEditor({
  type ActionOrStepProperties (line 623) | type ActionOrStepProperties =
  function StepEditorV2 (line 627) | function StepEditorV2() {
  type ConditionsAndMiscFormDataType (line 717) | type ConditionsAndMiscFormDataType =
  function ConditionsAndMiscEditor (line 734) | function ConditionsAndMiscEditor({
  type ActionOrStepFormDataType (line 787) | type ActionOrStepFormDataType = {
  function ActionOrStepEditor (line 793) | function ActionOrStepEditor({

FILE: keep-ui/features/workflows/builder/ui/Editor/StepTest.tsx
  function useTestStep (line 13) | function useTestStep() {
  function TestRunStepForm (line 75) | function TestRunStepForm({

FILE: keep-ui/features/workflows/builder/ui/Editor/TriggerEditor.tsx
  function TriggerEditor (line 19) | function TriggerEditor() {

FILE: keep-ui/features/workflows/builder/ui/Editor/WorkflowEditor.tsx
  function WorkflowEditorV2 (line 8) | function WorkflowEditorV2() {

FILE: keep-ui/features/workflows/builder/ui/NodeMenu.tsx
  function NodeMenu (line 9) | function NodeMenu({

FILE: keep-ui/features/workflows/builder/ui/WorkflowEdge.tsx
  function DebugEdgeInfo (line 12) | function DebugEdgeInfo({
  type WorkflowEdgeProps (line 46) | interface WorkflowEdgeProps extends EdgeProps {

FILE: keep-ui/features/workflows/builder/ui/WorkflowNode.tsx
  function DebugNodeInfo (line 25) | function DebugNodeInfo({ id, data }: Pick<FlowNode, "id" | "data">) {
  function IconUrlProvider (line 47) | function IconUrlProvider(data: FlowNode["data"]) {
  function ErrorIcon (line 56) | function ErrorIcon({ error }: { error: ValidationError | null }) {
  function WorkflowNode (line 89) | function WorkflowNode({ id, data }: FlowNode) {

FILE: keep-ui/features/workflows/builder/ui/WorkflowToolbox.tsx
  type GroupedMenuBaseProps (line 12) | type GroupedMenuBaseProps = {
  type GroupedMenuProps (line 18) | type GroupedMenuProps = GroupedMenuBaseProps &
  function IconUrlProvider (line 64) | function IconUrlProvider(data: any) {

FILE: keep-ui/features/workflows/builder/ui/workflow-status.tsx
  function ErrorList (line 11) | function ErrorList({

FILE: keep-ui/features/workflows/edit-metadata/ui/edit-workflow-metadata-form.tsx
  function EditWorkflowMetadataForm (line 6) | function EditWorkflowMetadataForm({

FILE: keep-ui/features/workflows/edit-metadata/ui/workflow-metadata-modal.tsx
  type Props (line 5) | interface Props {
  function WorkflowMetadataModal (line 18) | function WorkflowMetadataModal({

FILE: keep-ui/features/workflows/edit-workflow-metadata/ui/edit-workflow-metadata-form.tsx
  function EditWorkflowMetadataForm (line 6) | function EditWorkflowMetadataForm({

FILE: keep-ui/features/workflows/enable-disable/ui/WorkflowEnabledSwitch.tsx
  function WorkflowEnabledSwitch (line 5) | function WorkflowEnabledSwitch() {

FILE: keep-ui/features/workflows/manual-run-workflow/model/WorkflowModalContext.tsx
  type InputsModalProps (line 13) | type InputsModalProps = {
  type AlertDependenciesModalProps (line 18) | type AlertDependenciesModalProps = {
  type IncidentDependenciesModalProps (line 25) | type IncidentDependenciesModalProps = {
  type UnsavedChangesModalProps (line 32) | type UnsavedChangesModalProps = {
  type WorkflowModalContextType (line 38) | type WorkflowModalContextType = {
  function WorkflowModalProvider (line 54) | function WorkflowModalProvider({

FILE: keep-ui/features/workflows/manual-run-workflow/model/types.ts
  type AlertWorkflowRunPayload (line 1) | type AlertWorkflowRunPayload = {
  type IncidentWorkflowRunPayload (line 7) | type IncidentWorkflowRunPayload = {
  type InputsWorkflowRunPayload (line 13) | type InputsWorkflowRunPayload = {
  type WorkflowRunPayload (line 18) | type WorkflowRunPayload =

FILE: keep-ui/features/workflows/manual-run-workflow/ui/WorkflowInputsForm.tsx
  type WorkflowInputsFormProps (line 6) | interface WorkflowInputsFormProps {
  function WorkflowInputsForm (line 12) | function WorkflowInputsForm({

FILE: keep-ui/features/workflows/manual-run-workflow/ui/WorkflowUnsavedChangesForm.tsx
  function WorkflowUnsavedChangesForm (line 5) | function WorkflowUnsavedChangesForm({

FILE: keep-ui/features/workflows/manual-run-workflow/ui/manual-run-workflow-modal.tsx
  type Props (line 29) | interface Props {
  function ManualRunWorkflowModal (line 38) | function ManualRunWorkflowModal({

FILE: keep-ui/features/workflows/manual-run-workflow/ui/workflow-run-with-alert-modal.tsx
  type StaticField (line 9) | interface StaticField {
  type AlertTriggerModalProps (line 14) | interface AlertTriggerModalProps {
  type Field (line 22) | interface Field {
  function AlertTriggerModal (line 27) | function AlertTriggerModal({

FILE: keep-ui/features/workflows/test-run/ui/workflow-test-run-button.tsx
  type WorkflowTestRunButtonProps (line 24) | interface WorkflowTestRunButtonProps {
  function WorkflowTestRunButton (line 30) | function WorkflowTestRunButton({

FILE: keep-ui/instrumentation.ts
  function register (line 4) | async function register() {

FILE: keep-ui/jest.setup.ts
  method observe (line 7) | observe() {}
  method unobserve (line 8) | unobserve() {}
  method disconnect (line 9) | disconnect() {}

FILE: keep-ui/middleware.ts
  function isMobileDevice (line 9) | function isMobileDevice(userAgent: string): boolean {

FILE: keep-ui/next.config.js
  method redirects (line 115) | async redirects() {
  method headers (line 134) | async headers() {

FILE: keep-ui/proxyFetch.ts
  type ProxyFetchFn (line 4) | type ProxyFetchFn = (

FILE: keep-ui/scripts/generate-workflow-yaml-json-schema.ts
  function saveWorkflowYamlJsonSchema (line 6) | function saveWorkflowYamlJsonSchema() {

FILE: keep-ui/scripts/validate-workflow-examples.ts
  function getWorkflowExamplesFiles (line 7) | function getWorkflowExamplesFiles() {
  function validateWorkflowExamples (line 16) | function validateWorkflowExamples() {

FILE: keep-ui/shared/api/ApiClient.ts
  constant READ_ONLY_ALLOWED_METHODS (line 11) | const READ_ONLY_ALLOWED_METHODS = ["GET", "OPTIONS"];
  constant READ_ONLY_ALWAYS_ALLOWED_URLS (line 12) | const READ_ONLY_ALWAYS_ALLOWED_URLS = [
  type ApiClientOptions (line 21) | interface ApiClientOptions {
  class ApiClient (line 25) | class ApiClient {
    method constructor (line 29) | constructor(
    method isReady (line 38) | isReady() {
    method getHeaders (line 42) | getHeaders() {
    method getToken (line 57) | getToken() {
    method getApiBaseUrl (line 61) | getApiBaseUrl() {
    method handleResponse (line 72) | async handleResponse(response: Response, url: string) {
    method request (line 135) | async request<T = any>(
    method get (line 175) | async get<T = any>(url: string, requestInit: RequestInit = {}) {
    method post (line 179) | async post<T = any>(
    method put (line 195) | async put<T = any>(
    method patch (line 211) | async patch<T = any>(
    method delete (line 227) | async delete<T = any>(

FILE: keep-ui/shared/api/KeepApiError.ts
  class KeepApiError (line 2) | class KeepApiError extends Error {
    method constructor (line 7) | constructor(
    method toString (line 22) | toString() {
  class KeepApiReadOnlyError (line 27) | class KeepApiReadOnlyError extends KeepApiError {
    method constructor (line 28) | constructor(
  class KeepApiHealthError (line 40) | class KeepApiHealthError extends KeepApiError {
    method constructor (line 41) | constructor(message: string = "API server is not available") {
    method toString (line 49) | toString() {

FILE: keep-ui/shared/api/__tests__/ApiClient.test.ts
  function createMockResponse (line 17) | function createMockResponse(

FILE: keep-ui/shared/api/enrichment-events.ts
  type EnrichmentEventLog (line 1) | interface EnrichmentEventLog {
  type EnrichmentEventWithLogs (line 7) | interface EnrichmentEventWithLogs {
  type EnrichmentEvent (line 12) | interface EnrichmentEvent {
  type PaginatedEnrichmentExecutionDto (line 23) | interface PaginatedEnrichmentExecutionDto {

FILE: keep-ui/shared/api/providers.ts
  type ProviderAuthConfig (line 3) | interface ProviderAuthConfig {
  type ProviderMethodParam (line 28) | interface ProviderMethodParam {
  type ProviderMethod (line 36) | interface ProviderMethod {
  type ProviderScope (line 46) | interface ProviderScope {
  type ProvidersResponse (line 55) | interface ProvidersResponse {
  type AlertDistritbuionData (line 62) | interface AlertDistritbuionData {
  type TProviderCategory (line 67) | type TProviderCategory =
  type TProviderLabels (line 84) | type TProviderLabels =
  type Provider (line 93) | interface Provider {
  type Providers (line 142) | type Providers = Provider[];
  type ProviderFormKVData (line 164) | type ProviderFormKVData = Record<string, string>[];
  type ProviderFormValue (line 165) | type ProviderFormValue =
  type ProviderFormData (line 172) | type ProviderFormData = Record<string, ProviderFormValue>;
  type ProviderInputErrors (line 173) | type ProviderInputErrors = Record<string, string>;

FILE: keep-ui/shared/api/server/createServerApiClient.ts
  type OAuth2ProxyHeaderConfig (line 7) | interface OAuth2ProxyHeaderConfig {
  constant DEFAULT_OAUTH2_HEADERS (line 14) | const DEFAULT_OAUTH2_HEADERS: OAuth2ProxyHeaderConfig = {
  function getOAuth2HeaderConfig (line 21) | function getOAuth2HeaderConfig(): OAuth2ProxyHeaderConfig {
  function createServerApiClient (line 43) | async function createServerApiClient(): Promise<ApiClient> {

FILE: keep-ui/shared/api/workflow-executions.ts
  type LogEntry (line 3) | interface LogEntry {
  type WorkflowExecutionDetail (line 9) | interface WorkflowExecutionDetail {
  type PaginatedWorkflowExecutionDto (line 26) | interface PaginatedWorkflowExecutionDto {
  type WorkflowExecutionFailure (line 37) | type WorkflowExecutionFailure = Pick<WorkflowExecutionDetail, "error">;
  function isWorkflowExecution (line 39) | function isWorkflowExecution(
  function isWorkflowFailure (line 45) | function isWorkflowFailure(data: any): data is WorkflowExecutionFailure {

FILE: keep-ui/shared/api/workflows.ts
  type Provider (line 7) | type Provider = {
  type Filter (line 14) | type Filter = {
  type IncidentFilter (line 19) | type IncidentFilter = {
  type AlertFilter (line 24) | type AlertFilter = {
  type IntervalFilter (line 31) | type IntervalFilter = {
  type ManualFilter (line 36) | type ManualFilter = {
  type Trigger (line 40) | type Trigger =
  type LastWorkflowExecution (line 46) | type LastWorkflowExecution = {
  type Workflow (line 53) | type Workflow = {
  type MockProvider (line 76) | type MockProvider = {
  type MockCondition (line 89) | type MockCondition = {
  type MockAction (line 95) | type MockAction = {
  type MockStep (line 101) | type MockStep = {
  type MockTrigger (line 106) | type MockTrigger = {
  type MockWorkflow (line 110) | type MockWorkflow = {
  type WorkflowTemplate (line 120) | type WorkflowTemplate = {
  type PaginatedWorkflowsResults (line 127) | type PaginatedWorkflowsResults = {
  type WorkflowRevision (line 134) | type WorkflowRevision = {
  type WorkflowRevisionList (line 140) | type WorkflowRevisionList = {
  function getWorkflow (line 144) | async function getWorkflow(api: ApiClient, id: string) {
  function _getWorkflowWithRedirectSafe (line 154) | async function _getWorkflowWithRedirectSafe(

FILE: keep-ui/shared/constants.ts
  constant LOCALSTORAGE_THEME_KEY (line 1) | const LOCALSTORAGE_THEME_KEY = "theme";
  constant DOCS_CLIPBOARD_COPY_ERROR_PATH (line 3) | const DOCS_CLIPBOARD_COPY_ERROR_PATH =

FILE: keep-ui/shared/lib/__tests__/oauth2proxy-auth.test.ts
  function makeHeaders (line 69) | function makeHeaders(map: Record<string, string>): Headers {

FILE: keep-ui/shared/lib/downloadFileFromString.ts
  function downloadFileFromString (line 29) | function downloadFileFromString({

FILE: keep-ui/shared/lib/encodings.ts
  function dec2hex (line 8) | function dec2hex(dec: number) {
  function generateRandomString (line 21) | function generateRandomString() {
  function generatePkceVerifier (line 36) | function generatePkceVerifier(): string {
  function sha256 (line 54) | function sha256(plain: string) {
  function base64urlencode (line 75) | function base64urlencode(a: ArrayBuffer) {

FILE: keep-ui/shared/lib/getApiUrlFromConfig.ts
  function getApiUrlFromConfig (line 13) | function getApiUrlFromConfig(config: InternalConfig | null) {

FILE: keep-ui/shared/lib/hooks/useApi.tsx
  function useApi (line 7) | function useApi() {

FILE: keep-ui/shared/lib/hooks/useHealth.ts
  type UseHealthResult (line 5) | type UseHealthResult = {
  constant CACHE_DURATION (line 11) | const CACHE_DURATION = 30000;
  function useHealth (line 13) | function useHealth(): UseHealthResult {

FILE: keep-ui/shared/lib/hooks/useHydratedSession.tsx
  type Window (line 8) | interface Window {
  function useHydratedSession (line 15) | function useHydratedSession() {

FILE: keep-ui/shared/lib/hooks/useMounted.tsx
  function useMounted (line 3) | function useMounted() {

FILE: keep-ui/shared/lib/hooks/useSetSentryUser.ts
  type SentryUser (line 8) | type SentryUser = {
  function useSetSentryUser (line 16) | function useSetSentryUser({ session }: { session: Session | null }) {

FILE: keep-ui/shared/lib/hooks/useSignOut.ts
  function useSignOut (line 10) | function useSignOut() {

FILE: keep-ui/shared/lib/logs-utils.ts
  function getLogLineStatus (line 14) | function getLogLineStatus(log: LogEntry) {
  function getStepStatus (line 36) | function getStepStatus(

FILE: keep-ui/shared/lib/oauth2proxy-auth.ts
  type OAuth2HeaderConfig (line 3) | interface OAuth2HeaderConfig {
  function getOAuth2HeaderConfig (line 10) | function getOAuth2HeaderConfig(): OAuth2HeaderConfig {
  function authorizeOAuth2Proxy (line 27) | function authorizeOAuth2Proxy(

FILE: keep-ui/shared/lib/object-utils.ts
  function getNestedValue (line 22) | function getNestedValue(obj: any, path?: string | null): any {
  function buildNestedObject (line 66) | function buildNestedObject(

FILE: keep-ui/shared/lib/provider-utils.ts
  function isProviderInstalled (line 14) | function isProviderInstalled(

FILE: keep-ui/shared/lib/regex-utils.ts
  function extractNamedGroups (line 5) | function extractNamedGroups(regex: string): string[] {

FILE: keep-ui/shared/lib/server/getConfig.ts
  function getConfig (line 10) | function getConfig(): InternalConfig {

FILE: keep-ui/shared/lib/tremor-utils.ts
  function cx (line 63) | function cx(...args: ClassValue[]) {

FILE: keep-ui/shared/ui/DebugJSON/DebugJSON.tsx
  function DebugJSON (line 1) | function DebugJSON({

FILE: keep-ui/shared/ui/Drawer/Drawer.tsx
  function Drawer (line 15) | function Drawer({

FILE: keep-ui/shared/ui/DropdownMenu/DropdownMenu.tsx
  type MenuProps (line 49) | interface MenuProps {
  function handleTreeClick (line 123) | function handleTreeClick() {
  function onSubMenuOpen (line 127) | function onSubMenuOpen(event: { nodeId: string; parentId: string }) {
  method onClick (line 171) | onClick(event: React.MouseEvent<HTMLButtonElement>) {
  method onFocus (line 175) | onFocus(event: React.FocusEvent<HTMLButtonElement>) {
  type DropdownDropdownMenuItemProps (line 236) | interface DropdownDropdownMenuItemProps {
  method onClick (line 268) | onClick(event: React.MouseEvent<HTMLButtonElement>) {
  method onFocus (line 272) | onFocus(event: React.FocusEvent<HTMLButtonElement>) {

FILE: keep-ui/shared/ui/EmptyState/EmptyStateCard.tsx
  function EmptyStateCard (line 5) | function EmptyStateCard({

FILE: keep-ui/shared/ui/ErrorComponent/ErrorComponent.tsx
  function ErrorComponent (line 18) | function ErrorComponent({

FILE: keep-ui/shared/ui/FormattedContent/FormattedContent.tsx
  function FormattedHTMLContent (line 18) | function FormattedHTMLContent({
  type FormattedContentProps (line 45) | interface FormattedContentProps {

FILE: keep-ui/shared/ui/Input/index.tsx
  type InputProps (line 59) | interface InputProps

FILE: keep-ui/shared/ui/JsonCard/JsonCard.tsx
  function JsonCard (line 3) | function JsonCard({

FILE: keep-ui/shared/ui/KeepLoader/KeepLoader.tsx
  function KeepLoader (line 5) | function KeepLoader({

FILE: keep-ui/shared/ui/KeepLogoError/KeepLogoError.tsx
  type KeepLogoErrorProps (line 5) | interface KeepLogoErrorProps {

FILE: keep-ui/shared/ui/MonacoCELEditor/MonacoCel.tsx
  type MonacoCelProps (line 7) | interface MonacoCelProps extends EditorProps {
  function MonacoCelBase (line 16) | function MonacoCelBase(props: MonacoCelProps) {

FILE: keep-ui/shared/ui/MonacoCELEditor/MonacoCel.turbopack.tsx
  type MonacoCelProps (line 6) | interface MonacoCelProps extends EditorProps {
  function MonacoCelBase (line 11) | function MonacoCelBase(props: MonacoCelProps) {

FILE: keep-ui/shared/ui/MonacoCELEditor/handle-completions.ts
  type CompletionItemKind (line 4) | enum CompletionItemKind {
  type CompletionItemInsertTextRule (line 9) | enum CompletionItemInsertTextRule {
  function handleCompletions (line 13) | function handleCompletions(

FILE: keep-ui/shared/ui/MonacoCELEditor/monaco-cel-editor.tsx
  type MonacoCelProps (line 14) | interface MonacoCelProps {
  function MonacoCelEditor (line 26) | function MonacoCelEditor(props: MonacoCelProps) {

FILE: keep-ui/shared/ui/MonacoCELEditor/validation-hook.ts
  type CelExpressionValidationMarker (line 7) | interface CelExpressionValidationMarker {
  function useCelValidation (line 12) | function useCelValidation(

FILE: keep-ui/shared/ui/MonacoEditor/MonacoEditorCDN.tsx
  function MonacoEditorCDN (line 10) | function MonacoEditorCDN(props: EditorProps) {

FILE: keep-ui/shared/ui/MonacoEditor/MonacoEditorNPM.tsx
  function MonacoEditorNPM (line 16) | function MonacoEditorNPM(props: EditorProps) {

FILE: keep-ui/shared/ui/MonacoYAMLEditor/MonacoYAMLEditor.types.ts
  type MonacoYamlEditorProps (line 3) | type MonacoYamlEditorProps = {

FILE: keep-ui/shared/ui/MonacoYAMLEditor/editor.client.tsx
  method getWorker (line 13) | getWorker(_, label) {
  function MonacoYAMLEditor (line 47) | function MonacoYAMLEditor({

FILE: keep-ui/shared/ui/MonacoYAMLEditor/editor.client.turbopack.tsx
  method getWorker (line 22) | getWorker(_, label) {
  function MonacoYAMLEditorTurbopack (line 46) | function MonacoYAMLEditorTurbopack({

FILE: keep-ui/shared/ui/PostHogPageView.tsx
  function PostHogPageView (line 11) | function PostHogPageView(): null {

FILE: keep-ui/shared/ui/ResizableColumns/ui/ResizableColumns.tsx
  type ResizableColumnsProps (line 6) | interface ResizableColumnsProps {

FILE: keep-ui/shared/ui/Select/Select.tsx
  type OptionType (line 13) | type OptionType = { value: string; label: string; logoUrl?: string };
  function Select (line 56) | function Select<

FILE: keep-ui/shared/ui/SeverityBorderIcon/SeverityBorderIcon.tsx
  function SeverityBorderIcon (line 4) | function SeverityBorderIcon({ severity }: { severity: UISeverity }) {

FILE: keep-ui/shared/ui/SeverityLabel/SeverityLabel.tsx
  function SeverityLabel (line 9) | function SeverityLabel({ severity }: { severity: UISeverity }) {

FILE: keep-ui/shared/ui/TabLinkNavigation/TabLinkNavigation.tsx
  type TabLinkNavigationProps (line 4) | interface TabLinkNavigationProps {
  function TabLinkNavigation (line 10) | function TabLinkNavigation({

FILE: keep-ui/shared/ui/TabLinkNavigation/TabNavigationLink.tsx
  type TabNavigationLinkProps (line 7) | type TabNavigationLinkProps = {
  function TabNavigationLink (line 18) | function TabNavigationLink({

FILE: keep-ui/shared/ui/TableIndeterminateCheckbox/TableIndeterminateCheckbox.tsx
  function TableIndeterminateCheckbox (line 8) | function TableIndeterminateCheckbox({

FILE: keep-ui/shared/ui/TablePagination/TablePagination.tsx
  type Props (line 17) | type Props = {
  type OptionType (line 23) | interface OptionType {
  function TablePagination (line 38) | function TablePagination({ table }: Props) {

FILE: keep-ui/shared/ui/TableSeverityCell/TableSeverityCell.tsx
  function TableSeverityCell (line 4) | function TableSeverityCell({

FILE: keep-ui/shared/ui/Tooltip/Tooltip.tsx
  type TooltipProps (line 8) | interface TooltipProps

FILE: keep-ui/shared/ui/TraceViewer/Trace.ts
  type TraceSpan (line 1) | interface TraceSpan {
  type TraceData (line 19) | interface TraceData {

FILE: keep-ui/shared/ui/TraceViewer/TraceViewer.tsx
  type ProcessedSpan (line 13) | interface ProcessedSpan {
  type TypeIconProps (line 111) | interface TypeIconProps {

FILE: keep-ui/shared/ui/VerticalRoundedList/VerticalRoundedList.tsx
  function VerticalRoundedList (line 4) | function VerticalRoundedList({

FILE: keep-ui/shared/ui/WorkflowYAMLEditor/lib/useYamlValidation.ts
  type UseYamlValidationProps (line 16) | interface UseYamlValidationProps {
  constant SEVERITY_MAP (line 22) | const SEVERITY_MAP = {
  type UseYamlValidationResult (line 28) | interface UseYamlValidationResult {
  function useYamlValidation (line 43) | function useYamlValidation({

FILE: keep-ui/shared/ui/WorkflowYAMLEditor/lib/utils.ts
  type MarkerSeverity (line 8) | enum MarkerSeverity {
  function getSeverityString (line 15) | function getSeverityString(
  function isDiffEditorProps (line 30) | function isDiffEditorProps(
  function navigateToErrorPosition (line 36) | function navigateToErrorPosition(

FILE: keep-ui/shared/ui/WorkflowYAMLEditor/model/types.ts
  type YamlValidationErrorSeverity (line 3) | type YamlValidationErrorSeverity = "error" | "warning" | "info";
  type YamlValidationError (line 5) | type YamlValidationError = {
  type BaseWorkflowYAMLEditorProps (line 13) | interface BaseWorkflowYAMLEditorProps {
  type WorkflowYAMLEditorDefaultProps (line 29) | type WorkflowYAMLEditorDefaultProps = BaseWorkflowYAMLEditorProps & {
  type WorkflowYAMLEditorDiffProps (line 33) | type WorkflowYAMLEditorDiffProps = BaseWorkflowYAMLEditorProps & {
  type WorkflowYAMLEditorProps (line 38) | type WorkflowYAMLEditorProps =

FILE: keep-ui/shared/ui/WorkflowYAMLEditor/ui/WorkflowYAMLEditorStandalone.tsx
  function WorkflowYAMLEditorStandalone (line 15) | function WorkflowYAMLEditorStandalone({

FILE: keep-ui/shared/ui/WorkflowYAMLEditor/ui/WorkflowYAMLEditorToolbar.tsx
  type WorkflowYAMLEditorToolbarProps (line 6) | interface WorkflowYAMLEditorToolbarProps {
  function WorkflowYAMLEditorToolbar (line 15) | function WorkflowYAMLEditorToolbar({

FILE: keep-ui/shared/ui/WorkflowYAMLEditor/ui/WorkflowYAMLValidationErrors.tsx
  function WorkflowYAMLValidationErrors (line 13) | function WorkflowYAMLValidationErrors({

FILE: keep-ui/shared/ui/WorkflowYAMLEditor/ui/WorkflowYamlEditorHeader.tsx
  type WorkflowYamlEditorHeaderProps (line 5) | interface WorkflowYamlEditorHeaderProps {
  function WorkflowYamlEditorHeader (line 13) | function WorkflowYamlEditorHeader({

FILE: keep-ui/shared/ui/WorkflowYAMLEditorWithLogs/WorkflowYAMLEditorWithLogs.tsx
  type WorkflowYAMLEditorWithLogsProps (line 14) | type WorkflowYAMLEditorWithLogsProps = WorkflowYAMLEditorProps & {
  function WorkflowYAMLEditorWithLogs (line 24) | function WorkflowYAMLEditorWithLogs({

FILE: keep-ui/shared/ui/theme/ThemeControl.tsx
  constant THEMES (line 11) | const THEMES = {
  function ThemeControl (line 17) | function ThemeControl({ className }: { className?: string }) {

FILE: keep-ui/shared/ui/theme/WatchUpdateTheme.ts
  function WatchUpdateTheme (line 7) | function WatchUpdateTheme() {

FILE: keep-ui/shared/ui/utils/favicon.ts
  function setFavicon (line 1) | function setFavicon(status: string) {

FILE: keep-ui/shared/ui/utils/getIconForStatusString.tsx
  function getIconForStatusString (line 7) | function getIconForStatusString(status: string) {

FILE: keep-ui/shared/ui/utils/severity-utils.ts
  type UISeverity (line 2) | enum UISeverity {

FILE: keep-ui/shared/ui/utils/showErrorToast.tsx
  constant DEFAULT_TOAST_OPTIONS (line 5) | const DEFAULT_TOAST_OPTIONS: ToastOptions = {
  function showErrorToast (line 10) | function showErrorToast(

FILE: keep-ui/shared/ui/utils/showSuccessToast.tsx
  function showSuccessToast (line 8) | function showSuccessToast(

FILE: keep-ui/types/auth.d.ts
  type Session (line 5) | interface Session {
  type User (line 20) | interface User {
  type JWT (line 37) | interface JWT {
  type GuestSession (line 49) | interface GuestSession {

FILE: keep-ui/types/internal-config.ts
  type InternalConfig (line 1) | interface InternalConfig {

FILE: keep-ui/types/react-table.d.ts
  type ColumnMeta (line 4) | interface ColumnMeta<TData extends RowData, TValue> {

FILE: keep-ui/utils/apiUrl.ts
  function getApiURL (line 2) | function getApiURL(): string {

FILE: keep-ui/utils/authenticationType.ts
  type AuthType (line 3) | enum AuthType {
  constant MULTI_TENANT (line 15) | const MULTI_TENANT = "MULTI_TENANT";
  constant SINGLE_TENANT (line 16) | const SINGLE_TENANT = "SINGLE_TENANT";
  constant NO_AUTH (line 17) | const NO_AUTH = "NO_AUTH";

FILE: keep-ui/utils/cel-ast.ts
  type LogicalNodeOperator (line 2) | enum LogicalNodeOperator {
  type ComparisonNodeOperator (line 7) | enum ComparisonNodeOperator {
  type UnaryNodeOperator (line 20) | enum UnaryNodeOperator {
  type DataType (line 25) | enum DataType {
  type Node (line 37) | interface Node {
  type ConstantNode (line 41) | interface ConstantNode extends Node {
  type ParenthesisNode (line 45) | interface ParenthesisNode extends Node {
  type LogicalNode (line 49) | interface LogicalNode extends Node {
  type ComparisonNode (line 55) | interface ComparisonNode extends Node {
  type UnaryNode (line 61) | interface UnaryNode extends Node {
  type PropertyAccessNode (line 66) | interface PropertyAccessNode extends Node {

FILE: keep-ui/utils/fatigue.ts
  constant WINDOW_SIZE (line 3) | const WINDOW_SIZE = 60 * 60 * 1000;
  constant MAX_ALERTS_PER_WINDOW (line 4) | const MAX_ALERTS_PER_WINDOW = 50;

FILE: keep-ui/utils/helpers.ts
  function onlyUnique (line 4) | function onlyUnique(value: string, index: number, array: string[]) {
  function isValidDate (line 8) | function isValidDate(d: Date) {
  function capitalize (line 12) | function capitalize(string: string) {
  function toDateObjectWithFallback (line 16) | function toDateObjectWithFallback(date: string | Date) {
  function cn (line 38) | function cn(...inputs: ClassValue[]) {
  function areSetsEqual (line 42) | function areSetsEqual<T>(set1: Set<T>, set2: Set<T>): boolean {

FILE: keep-ui/utils/hooks/useAI.ts
  type UseAIActionsValue (line 38) | type UseAIActionsValue = {
  function useAIActions (line 45) | function useAIActions(): UseAIActionsValue {

FILE: keep-ui/utils/hooks/useDashboardMetricWidgets.ts
  type MetricsWidget (line 5) | interface MetricsWidget {
  type DistributionData (line 11) | interface DistributionData {
  type DashboardDistributionData (line 16) | interface DashboardDistributionData {

FILE: keep-ui/utils/hooks/useDashboards.ts
  type Dashboard (line 4) | interface Dashboard {

FILE: keep-ui/utils/hooks/useDebouncedValue.ts
  function useDebouncedValue (line 5) | function useDebouncedValue<T = any>(

FILE: keep-ui/utils/hooks/useEnrichmentEvents.ts
  type UseEnrichmentEventsOptions (line 9) | interface UseEnrichmentEventsOptions {
  function useEnrichmentEvents (line 17) | function useEnrichmentEvents({
  type UseEnrichmentEventOptions (line 44) | interface UseEnrichmentEventOptions {
  function useEnrichmentEvent (line 51) | function useEnrichmentEvent({

FILE: keep-ui/utils/hooks/useExpandedRows.ts
  function useExpandedRows (line 7) | function useExpandedRows(presetName: string) {

FILE: keep-ui/utils/hooks/useGroupExpansion.ts
  type GroupExpansionState (line 3) | interface GroupExpansionState {
  function useGroupExpansion (line 7) | function useGroupExpansion(defaultExpanded: boolean = true) {

FILE: keep-ui/utils/hooks/useIncidents.ts
  type IncidentUpdatePayload (line 19) | interface IncidentUpdatePayload {
  type Filters (line 23) | interface Filters {
  type IncidentsQuery (line 31) | interface IncidentsQuery {
  function getQueryParams (line 40) | function getQueryParams(query: IncidentsQuery | null): URLSearchParams |...

FILE: keep-ui/utils/hooks/useLocalStorage.ts
  constant STORAGE_EVENT (line 6) | const STORAGE_EVENT = "keephq";
  function getSnapshot (line 8) | function getSnapshot(key: string): string | null {
  function getParsedJson (line 21) | function getParsedJson<T>(
  function subscribe (line 68) | function subscribe(callback: () => void) {

FILE: keep-ui/utils/hooks/useProviderLogs.ts
  type ProviderLog (line 6) | interface ProviderLog {
  type UseProviderLogsOptions (line 17) | interface UseProviderLogsOptions {
  function useProviderLogs (line 25) | function useProviderLogs({

FILE: keep-ui/utils/hooks/usePusher.ts
  constant PUSHER (line 6) | let PUSHER: Pusher | null = null;

FILE: keep-ui/utils/hooks/useRules.ts
  type Rule (line 5) | type Rule = {

FILE: keep-ui/utils/hooks/useWorkflowSecrets.ts
  function useWorkflowSecrets (line 5) | function useWorkflowSecrets(workflowId: string | null | undefined) {

FILE: keep-ui/utils/reactFlow.ts
  function reConstructWorklowToDefinition (line 21) | function reConstructWorklowToDefinition({
  function createSwitchNodeV2 (line 172) | function createSwitchNodeV2(
  function handleSwitchNode (line 229) | function handleSwitchNode(
  function createCustomEdgeMeta (line 362) | function createCustomEdgeMeta(
  function handleDefaultNode (line 391) | function handleDefaultNode(
  function getForEachNode (line 427) | function getForEachNode(
  function handleForeachNode (line 470) | function handleForeachNode(
  function getTriggerSteps (line 631) | function getTriggerSteps(properties: V2Properties) {

FILE: keep-ui/utils/type-utils.ts
  type InterfaceToType (line 1) | type InterfaceToType<T> = {

FILE: keep-ui/widgets/alerts-table/lib/alert-table-list-format.tsx
  type ListFormatOption (line 7) | type ListFormatOption =
  type ListItem (line 16) | interface ListItem {

FILE: keep-ui/widgets/alerts-table/lib/alert-table-time-format.tsx
  type TimeFormatOption (line 7) | type TimeFormatOption =

FILE: keep-ui/widgets/alerts-table/lib/alert-table-utils.tsx
  constant DEFAULT_COLS (line 59) | const DEFAULT_COLS = [
  constant DEFAULT_COLS_VISIBILITY (line 70) | const DEFAULT_COLS_VISIBILITY = DEFAULT_COLS.reduce<VisibilityState>(
  type CustomCell (line 149) | type CustomCell = {
  type GenerateAlertTableColsArg (line 191) | interface GenerateAlertTableColsArg {

FILE: keep-ui/widgets/alerts-table/ui/ActionTraySelection.tsx
  type ActionTraySelectionProps (line 4) | interface ActionTraySelectionProps {
  function ActionTraySelection (line 8) | function ActionTraySelection({ onClose }: ActionTraySelectionProps) {

FILE: keep-ui/widgets/alerts-table/ui/ColumnSelection.tsx
  type AlertColumnsSelectProps (line 9) | interface AlertColumnsSelectProps {
  function ColumnSelection (line 16) | function ColumnSelection({

FILE: keep-ui/widgets/alerts-table/ui/RowStyleSelection.tsx
  type RowStyleSelectionProps (line 7) | interface RowStyleSelectionProps {
  function RowStyleSelection (line 11) | function RowStyleSelection({ onClose }: RowStyleSelectionProps) {

FILE: keep-ui/widgets/alerts-table/ui/SettingsSelection.tsx
  type SettingsSelectionProps (line 21) | interface SettingsSelectionProps {
  function SettingsSelection (line 27) | function SettingsSelection({

FILE: keep-ui/widgets/alerts-table/ui/TitleAndFilters.tsx
  type TableHeaderProps (line 10) | type TableHeaderProps = {

FILE: keep-ui/widgets/alerts-table/ui/alert-actions.tsx
  type Props (line 19) | interface Props {
  function AlertActions (line 31) | function AlertActions({

FILE: keep-ui/widgets/alerts-table/ui/alert-assignee.tsx
  type Props (line 5) | interface Props {
  function AlertAssignee (line 9) | function AlertAssignee({ assignee }: Props) {

FILE: keep-ui/widgets/alerts-table/ui/alert-extra-payload.tsx
  type Props (line 15) | interface Props {
  function AlertExtraPayload (line 21) | function AlertExtraPayload({

FILE: keep-ui/widgets/alerts-table/ui/alert-grouped-row.tsx
  type GroupedRowProps (line 14) | interface GroupedRowProps {

FILE: keep-ui/widgets/alerts-table/ui/alert-pagination.tsx
  type Props (line 16) | interface Props {
  type OptionType (line 22) | interface OptionType {
  function AlertPagination (line 37) | function AlertPagination({

FILE: keep-ui/widgets/alerts-table/ui/alert-table-column-rename.tsx
  type ColumnRenameMapping (line 8) | type ColumnRenameMapping = Record<string, string>;

FILE: keep-ui/widgets/alerts-table/ui/alert-table-headers.tsx
  type DraggableHeaderCellProps (line 67) | interface DraggableHeaderCellProps {
  type Props (line 422) | interface Props {
  function AlertsTableHeaders (line 439) | function AlertsTableHeaders({

FILE: keep-ui/widgets/alerts-table/ui/alert-table-server-side.tsx
  type PresetTab (line 86) | interface PresetTab {
  type Tab (line 92) | interface Tab {
  type Props (line 98) | interface Props {
  function AlertTableServerSide (line 120) | function AlertTableServerSide({

FILE: keep-ui/widgets/alerts-table/ui/alert-table.tsx
  type PresetTab (line 53) | interface PresetTab {
  type Props (line 59) | interface Props {
  function AlertTable (line 95) | function AlertTable({

FILE: keep-ui/widgets/alerts-table/ui/alerts-table-body.tsx
  type Props (line 17) | interface Props {
  function AlertsTableBody (line 28) | function AlertsTableBody({

FILE: keep-ui/widgets/alerts-table/ui/useAlertsTableData.ts
  type AlertsTableDataQuery (line 7) | interface AlertsTableDataQuery {
  function getDateRangeCel (line 16) | function getDateRangeCel(timeFrame: TimeFrameV2 | null): string | null {
  function updateAlertsCelDateRange (line 80) | function updateAlertsCelDateRange() {

FILE: keep-ui/widgets/workflow-builder/empty-builder-state.tsx
  function EmptyBuilderState (line 3) | function EmptyBuilderState() {

FILE: keep-ui/widgets/workflow-builder/workflow-builder-card.tsx
  type Props (line 17) | interface Props {
  function WorkflowBuilderCard (line 24) | function WorkflowBuilderCard({

FILE: keep-ui/widgets/workflow-builder/workflow-builder-widget-safe.tsx
  function WorkflowBuilderWidgetSafe (line 10) | function WorkflowBuilderWidgetSafe(props: WorkflowBuilderWidgetProps) {

FILE: keep-ui/widgets/workflow-builder/workflow-builder-widget.tsx
  type WorkflowBuilderWidgetProps (line 17) | interface WorkflowBuilderWidgetProps {
  function WorkflowBuilderWidget (line 23) | function WorkflowBuilderWidget({

FILE: keep-ui/widgets/workflow-builder/workflow-builder.tsx
  type Props (line 26) | interface Props {
  function WorkflowBuilder (line 34) | function WorkflowBuilder({

FILE: keep/actions/actions_exception.py
  class ActionsCRUDException (line 3) | class ActionsCRUDException(HTTPException):

FILE: keep/actions/actions_factory.py
  class ActionsCRUD (line 15) | class ActionsCRUD:
    method get_all_actions (line 18) | def get_all_actions(tenant_id: str) -> List[ActionDTO]:
    method _convert_models_to_dtos (line 23) | def _convert_models_to_dtos(models: List[Action]) -> List[ActionDTO]:
    method add_actions (line 37) | def add_actions(tenant_id: str, installed_by: str, action_dtos: List[d...
    method remove_action (line 57) | def remove_action(tenant_id: str, action_id: str):
    method get_action (line 66) | def get_action(tenant_id: str, action_id: str) -> Union[Action, None]:
    method update_action (line 74) | def update_action(tenant_id: str, action_id: str, payload: dict) -> Un...

FILE: keep/api/alert_deduplicator/alert_deduplicator.py
  class AlertDeduplicator (line 32) | class AlertDeduplicator:
    method __init__ (line 41) | def __init__(self, tenant_id):
    method _apply_deduplication_rule (line 45) | def _apply_deduplication_rule(
    method apply_deduplication (line 118) | def apply_deduplication(
    method _remove_field (line 180) | def _remove_field(self, field, alert: AlertDto) -> AlertDto:
    method get_deduplication_rules (line 197) | def get_deduplication_rules(
    method _generate_uuid (line 247) | def _generate_uuid(self, provider_id, provider_type):
    method _get_default_full_deduplication_rule (line 260) | def _get_default_full_deduplication_rule(
    method get_deduplications (line 292) | def get_deduplications(self) -> list[DeduplicationRuleDto]:
    method get_deduplication_fields (line 463) | def get_deduplication_fields(self) -> list[str]:
    method create_deduplication_rule (line 477) | def create_deduplication_rule(
    method update_deduplication_rule (line 522) | def update_deduplication_rule(
    method delete_deduplication_rule (line 579) | def delete_deduplication_rule(self, rule_id: str) -> bool:

FILE: keep/api/alert_deduplicator/deduplication_rules_provisioning.py
  function provision_deduplication_rules (line 12) | def provision_deduplication_rules(deduplication_rules: dict[str, any], t...
  function provision_deduplication_rules_from_env (line 101) | def provision_deduplication_rules_from_env(tenant_id: str):
  function enrich_with_providers_info (line 124) | def enrich_with_providers_info(deduplication_rules: dict[str, any], tena...
  function get_deduplication_rules_to_provision (line 145) | def get_deduplication_rules_to_provision() -> dict[str, dict]:

FILE: keep/api/api.py
  function no_redirect_request (line 100) | def no_redirect_request(self, method, url, **kwargs):
  function check_pending_tasks (line 108) | async def check_pending_tasks(background_tasks: set):
  function startup (line 120) | async def startup():
  function shutdown (line 193) | async def shutdown():
  function lifespan (line 223) | async def lifespan(app: FastAPI):
  function get_app (line 246) | def get_app(
  function wrap_call (line 386) | def wrap_call(middleware_cls, original_call):
  function instrument_middleware (line 418) | def instrument_middleware(app):
  function run (line 429) | def run(app: FastAPI):

FILE: keep/api/arq_pool.py
  function get_pool (line 4) | async def get_pool():

FILE: keep/api/arq_worker.py
  function process_event_in_worker (line 69) | async def process_event_in_worker(
  function startup (line 125) | async def startup(ctx):
  function shutdown (line 135) | async def shutdown(ctx):
  function at_every_x_minutes (line 142) | def at_every_x_minutes(x: int, start: int = 0, end: int = 59):
  class WorkerSettings (line 150) | class WorkerSettings:
    method __init__ (line 165) | def __init__(self, queue_name: str):
  function get_arq_worker (line 169) | def get_arq_worker(queue_name: str) -> Worker:
  function safe_run_worker (line 198) | async def safe_run_worker(worker: Worker, number_of_errors_before_restar...

FILE: keep/api/arq_worker_debug_patch.py
  function log_function_call (line 22) | def log_function_call(func):
  function patched_run_job (line 47) | async def patched_run_job(self, job_id: str, score: int) -> None:
  function patched_finish_job (line 89) | async def patched_finish_job(
  function patched_start_jobs (line 153) | async def patched_start_jobs(self, job_ids: list) -> None:
  function patched_pipeline_execute (line 167) | async def patched_pipeline_execute(self, *args, **kwargs):
  function apply_arq_debug_patches (line 179) | def apply_arq_debug_patches():
  function patch_process_event (line 224) | def patch_process_event():
  function dump_job_state (line 251) | async def dump_job_state(redis_pool, job_id: str):

FILE: keep/api/arq_worker_gunicorn.py
  function determine_queue_name (line 33) | def determine_queue_name():
  function run_arq_worker (line 49) | async def run_arq_worker(worker_id, number_of_errors_before_restart=0):
  class ARQGunicornWorker (line 106) | class ARQGunicornWorker(Worker):
    method __init__ (line 112) | def __init__(self, *args, **kwargs):
    method update_heartbeat (line 140) | def update_heartbeat(self):
    method start_heartbeat_thread (line 150) | def start_heartbeat_thread(self):
    method check_heartbeat (line 164) | def check_heartbeat(self):
    method handle_http_request (line 189) | async def handle_http_request(self, reader, writer):
    method _run (line 222) | async def _run(self):
    method init_process (line 246) | def init_process(self):
    method run (line 260) | def run(self):
    method handle_signal (line 315) | async def handle_signal(self, sig):
  function create_app (line 332) | def create_app():

FILE: keep/api/bl/ai_suggestion_bl.py
  class AISuggestionBl (line 26) | class AISuggestionBl:
    method __init__ (line 27) | def __init__(self, tenant_id: str, session: Session | None = None) -> ...
    method get_suggestion_by_input (line 47) | def get_suggestion_by_input(self, suggestion_input: Dict) -> Optional[...
    method hash_suggestion_input (line 67) | def hash_suggestion_input(self, suggestion_input: Dict) -> str:
    method add_suggestion (line 81) | def add_suggestion(
    method add_feedback (line 140) | def add_feedback(
    method get_feedback (line 198) | def get_feedback(
    method suggest_incidents (line 232) | def suggest_incidents(
    method commit_incidents (line 297) | async def commit_incidents(
    method _prepare_prompts (line 351) | def _prepare_prompts(
    method _get_ai_completion (line 404) | def _get_ai_completion(self, system_prompt: str, user_prompt: str):
    method _process_incidents (line 467) | def _process_incidents(

FILE: keep/api/bl/dismissal_expiry_bl.py
  class DismissalExpiryBl (line 22) | class DismissalExpiryBl:
    method get_alerts_with_expired_dismissals (line 25) | def get_alerts_with_expired_dismissals(session: Session) -> List[Alert...
    method check_dismissal_expiry (line 121) | def check_dismissal_expiry(logger: logging.Logger, session: Optional[S...

FILE: keep/api/bl/enrichments_bl.py
  function is_valid_uuid (line 49) | def is_valid_uuid(uuid_str):
  function get_nested_attribute (line 60) | def get_nested_attribute(obj: AlertDto, attr_path: str):
  class EnrichmentsBl (line 91) | class EnrichmentsBl:
    method __init__ (line 95) | def __init__(self, tenant_id: str, db: Session | None = None):
    method run_mapping_rule_by_id (line 107) | def run_mapping_rule_by_id(self, rule_id: int, alert_id: UUID) -> Aler...
    method run_extraction_rule_by_id (line 119) | def run_extraction_rule_by_id(self, rule_id: int, alert: Alert) -> Ale...
    method run_extraction_rules (line 130) | def run_extraction_rules(
    method run_mapping_rules (line 297) | def run_mapping_rules(self, alert: AlertDto) -> AlertDto:
    method check_if_match_and_enrich (line 340) | def check_if_match_and_enrich(self, alert: AlertDto, rule: MappingRule...
    method _is_match (line 525) | def _is_match(value, pattern):
    method _check_explicit_match (line 530) | def _check_explicit_match(
    method _check_matcher (line 546) | def _check_matcher(
    method get_enrichment_metadata (line 586) | def get_enrichment_metadata(
    method batch_enrich (line 641) | def batch_enrich(
    method disposable_enrich_entity (line 683) | def disposable_enrich_entity(
    method enrich_entity (line 723) | def enrich_entity(
    method get_total_enrichment_events (line 803) | def get_total_enrichment_events(
    method get_enrichment_event (line 813) | def get_enrichment_event(self, enrichment_event_id: UUID) -> Enrichmen...
    method get_enrichment_events (line 823) | def get_enrichment_events(
    method get_enrichment_event_logs (line 844) | def get_enrichment_event_logs(self, enrichment_event_id: UUID):
    method dispose_enrichments (line 851) | def dispose_enrichments(self, fingerprint: str):
    method _track_enrichment_event (line 897) | def _track_enrichment_event(
    method _add_enrichment_log (line 947) | def _add_enrichment_log(
    method check_incident_resolution (line 972) | def check_incident_resolution(self, alert: Alert | AlertDto):

FILE: keep/api/bl/incident_reports.py
  class IncidentMetrics (line 17) | class IncidentMetrics(BaseModel):
  class IncidentDurations (line 24) | class IncidentDurations(BaseModel):
  class IncidentReportDto (line 31) | class IncidentReportDto(BaseModel):
  class ReoccuringIncidentReportDto (line 36) | class ReoccuringIncidentReportDto(IncidentReportDto):
  class IncidentReport (line 40) | class IncidentReport(BaseModel):
  class OpenAIReportPart (line 50) | class OpenAIReportPart(BaseModel):
  class IncidentReportsBl (line 79) | class IncidentReportsBl:
    method open_ai_client (line 83) | def open_ai_client(self):
    method __init__ (line 89) | def __init__(self, tenant_id: str):
    method get_incident_reports (line 95) | def get_incident_reports(
    method __calculate_report_in_openai (line 122) | def __calculate_report_in_openai(
    method __calculate_top_services_affected (line 181) | def __calculate_top_services_affected(
    method __calculate_severity_metrics (line 195) | def __calculate_severity_metrics(
    method __calculate_mttd (line 212) | def __calculate_mttd(self, incidents: list[IncidentDto]) -> int:
    method __calculate_mttr (line 230) | def __calculate_mttr(self, resolved_incidents: list[IncidentDto]) -> int:
    method __calculate_durations (line 245) | def __calculate_durations(
    method __calculate_recurring_incidents (line 277) | def __calculate_recurring_incidents(
    method __get_incidents (line 321) | def __get_incidents(

FILE: keep/api/bl/incidents_bl.py
  class IncidentBl (line 58) | class IncidentBl:
    method __init__ (line 60) | def __init__(
    method create_incident (line 75) | def create_incident(
    method sync_add_alerts_to_incident (line 121) | def sync_add_alerts_to_incident(self, *args, **kwargs) -> None:
    method add_alerts_to_incident (line 127) | async def add_alerts_to_incident(
    method __update_elastic (line 172) | def __update_elastic(self, alert_fingerprints: List[str]):
    method update_client_on_incident_change (line 192) | def update_client_on_incident_change(self, incident_id: Optional[UUID]...
    method send_workflow_event (line 214) | def send_workflow_event(self, incident_dto: IncidentDto, action: str) ...
    method __generate_summary (line 224) | async def __generate_summary(self, incident_id: UUID, incident: Incide...
    method delete_alerts_from_incident (line 254) | def delete_alerts_from_incident(
    method delete_incident (line 273) | def delete_incident(self, incident_id: UUID) -> None:
    method bulk_delete_incidents (line 297) | def bulk_delete_incidents(self, incident_ids: List[UUID]) -> None:
    method update_incident (line 301) | def update_incident(
    method __postprocess_alerts_change (line 319) | def __postprocess_alerts_change(self, incident, alert_fingerprints):
    method update_severity (line 347) | def update_severity(
    method __postprocess_incident_change (line 377) | def __postprocess_incident_change(self, incident):
    method query_incidents (line 396) | def query_incidents(
    method resolve_incident_if_require (line 432) | def resolve_incident_if_require(
    method change_status (line 478) | def change_status(

FILE: keep/api/bl/maintenance_windows_bl.py
  class MaintenanceWindowsBl (line 33) | class MaintenanceWindowsBl:
    method __init__ (line 35) | def __init__(self, tenant_id: str, session: Session | None) -> None:
    method check_if_alert_in_maintenance_windows (line 48) | def check_if_alert_in_maintenance_windows(self, alert: AlertDto) -> bool:
    method evaluate_cel (line 121) | def evaluate_cel(maintenance_window: MaintenanceWindowRule, alert: Ale...
    method recover_strategy (line 155) | def recover_strategy(

FILE: keep/api/config.py
  function provision_resources (line 25) | def provision_resources():
  function on_starting (line 43) | def on_starting(server=None):
  function post_worker_init (line 100) | def post_worker_init(worker):

FILE: keep/api/core/alerts.py
  function get_threeshold_query (line 220) | def get_threeshold_query(tenant_id: str):
  function __build_query_for_filtering (line 233) | def __build_query_for_filtering(
  function build_total_alerts_query (line 321) | def build_total_alerts_query(tenant_id, query: QueryDto):
  function build_alerts_query (line 341) | def build_alerts_query(tenant_id, query: QueryDto):
  function query_last_alerts (line 380) | def query_last_alerts(tenant_id, query: QueryDto) -> Tuple[list[Alert], ...
  function get_alert_facets_data (line 447) | def get_alert_facets_data(
  function get_alert_facets (line 481) | def get_alert_facets(
  function get_alert_potential_facet_fields (line 504) | def get_alert_potential_facet_fields(tenant_id: str) -> list[str]:

FILE: keep/api/core/cel_to_sql/ast_nodes.py
  class Node (line 10) | class Node(BaseModel):
    method __init__ (line 18) | def __init__(self, **data):
  class ConstantNode (line 24) | class ConstantNode(Node):
    method __str__ (line 38) | def __str__(self):
  class ParenthesisNode (line 41) | class ParenthesisNode(Node):
    method __str__ (line 54) | def __str__(self):
  class LogicalNodeOperator (line 58) | class LogicalNodeOperator(Enum):
  class LogicalNode (line 63) | class LogicalNode(Node):
    method __str__ (line 84) | def __str__(self):
  class ComparisonNodeOperator (line 88) | class ComparisonNodeOperator(Enum):
  class ComparisonNode (line 101) | class ComparisonNode(Node):
    method __str__ (line 122) | def __str__(self):
  class UnaryNodeOperator (line 126) | class UnaryNodeOperator(Enum):
  class UnaryNode (line 132) | class UnaryNode(Node):
    method __str__ (line 151) | def __str__(self):
  class MemberAccessNode (line 159) | class MemberAccessNode(Node):
    method __str__ (line 170) | def __str__(self):
  class MethodAccessNode (line 175) | class MethodAccessNode(MemberAccessNode):
    method copy (line 201) | def copy(self):
    method __str__ (line 206) | def __str__(self):
  class DataType (line 215) | class DataType(Enum):
  function from_type_to_data_type (line 241) | def from_type_to_data_type(_type: type) -> DataType:
  class PropertyAccessNode (line 264) | class PropertyAccessNode(MemberAccessNode):
    method is_function_call (line 289) | def is_function_call(self) -> bool:
    method get_property_path (line 295) | def get_property_path(self) -> list[str]:
    method get_method_access_node (line 299) | def get_method_access_node(self) -> MethodAccessNode:
    method __str__ (line 308) | def __str__(self):

FILE: keep/api/core/cel_to_sql/cel_ast_converter.py
  class CelToAstConverter (line 48) | class CelToAstConverter(lark.visitors.Visitor_Recursive):
    method convert_to_ast (line 52) | def convert_to_ast(cls_, cel: str) -> Node:
    method __init__ (line 62) | def __init__(self) -> None:
    method expr (line 67) | def expr(self, tree: lark.Tree) -> None:
    method conditionalor (line 78) | def conditionalor(self, tree: lark.Tree) -> None:
    method conditionaland (line 88) | def conditionaland(self, tree: lark.Tree) -> None:
    method relation (line 98) | def relation(self, tree: lark.Tree) -> None:
    method relation_lt (line 109) | def relation_lt(self, tree: lark.Tree) -> None:
    method relation_le (line 118) | def relation_le(self, tree: lark.Tree) -> None:
    method relation_gt (line 127) | def relation_gt(self, tree: lark.Tree) -> None:
    method relation_ge (line 136) | def relation_ge(self, tree: lark.Tree) -> None:
    method relation_eq (line 145) | def relation_eq(self, tree: lark.Tree) -> None:
    method relation_ne (line 154) | def relation_ne(self, tree: lark.Tree) -> None:
    method relation_in (line 163) | def relation_in(self, tree: lark.Tree) -> None:
    method addition (line 172) | def addition(self, tree: lark.Tree) -> None:
    method addition_add (line 181) | def addition_add(self, tree: lark.Tree) -> None:
    method addition_sub (line 188) | def addition_sub(self, tree: lark.Tree) -> None:
    method multiplication (line 195) | def multiplication(self, tree: lark.Tree) -> None:
    method multiplication_mul (line 204) | def multiplication_mul(self, tree: lark.Tree) -> None:
    method multiplication_div (line 211) | def multiplication_div(self, tree: lark.Tree) -> None:
    method multiplication_mod (line 218) | def multiplication_mod(self, tree: lark.Tree) -> None:
    method unary (line 225) | def unary(self, tree: lark.Tree) -> None:
    method unary_not (line 234) | def unary_not(self, tree: lark.Tree) -> None:
    method unary_neg (line 237) | def unary_neg(self, tree: lark.Tree) -> None:
    method member_dot (line 240) | def member_dot(self, tree: lark.Tree) -> None:
    method member_dot_arg (line 252) | def member_dot_arg(self, tree: lark.Tree) -> None:
    method member_index (line 278) | def member_index(self, tree: lark.Tree) -> None:
    method member_object (line 292) | def member_object(self, tree: lark.Tree) -> None:
    method dot_ident_arg (line 295) | def dot_ident_arg(self, tree: lark.Tree) -> None:
    method dot_ident (line 298) | def dot_ident(self, tree: lark.Tree) -> None:
    method ident_arg (line 301) | def ident_arg(self, tree: lark.Tree) -> None:
    method ident (line 314) | def ident(self, tree: lark.Tree) -> None:
    method paren_expr (line 322) | def paren_expr(self, tree: lark.Tree) -> None:
    method list_lit (line 328) | def list_lit(self, tree: lark.Tree) -> None:
    method map_lit (line 333) | def map_lit(self, tree: lark.Tree) -> None:
    method exprlist (line 336) | def exprlist(self, tree: lark.Tree) -> None:
    method fieldinits (line 340) | def fieldinits(self, tree: lark.Tree) -> None:
    method mapinits (line 343) | def mapinits(self, tree: lark.Tree) -> None:
    method literal (line 346) | def literal(self, tree: lark.Tree) -> None:
    method to_constant_node (line 352) | def to_constant_node(self, value: str) -> ConstantNode:
    method is_number (line 374) | def is_number(self, value: str) -> bool:
    method is_float (line 381) | def is_float(self, value: str) -> bool:
    method is_date (line 388) | def is_date(self, value: str) -> bool:

FILE: keep/api/core/cel_to_sql/properties_mapper.py
  class JsonPropertyAccessNode (line 25) | class JsonPropertyAccessNode(PropertyAccessNode):
    method __init__ (line 37) | def __init__(
  class MultipleFieldsNode (line 55) | class MultipleFieldsNode(Node):
  class PropertiesMappingException (line 69) | class PropertiesMappingException(Exception):
  class PropertiesMapper (line 78) | class PropertiesMapper:
    method __init__ (line 101) | def __init__(self, properties_metadata: PropertiesMetadata):
    method map_props_in_ast (line 104) | def map_props_in_ast(
    method __visit_nodes (line 115) | def __visit_nodes(
    method __visit_unary_node (line 153) | def __visit_unary_node(
    method __visit_comparison_node (line 177) | def __visit_comparison_node(
    method _visit_member_access_node (line 198) | def _visit_member_access_node(
    method _modify_comparison_node_based_on_mapping (line 240) | def _modify_comparison_node_based_on_mapping(
    method _create_property_access_node (line 344) | def _create_property_access_node(
    method _map_property (line 362) | def _map_property(

FILE: keep/api/core/cel_to_sql/properties_metadata.py
  class SimpleFieldMapping (line 7) | class SimpleFieldMapping:
    method __init__ (line 8) | def __init__(self, map_to: str):
  class JsonFieldMapping (line 12) | class JsonFieldMapping:
    method __init__ (line 14) | def __init__(self, json_prop: str, prop_in_json: list[str]):
  class PropertyMetadataInfo (line 19) | class PropertyMetadataInfo:
    method __init__ (line 21) | def __init__(
  class FieldMappingConfiguration (line 34) | class FieldMappingConfiguration:
    method __init__ (line 36) | def __init__(
  function remap_fields_configurations (line 49) | def remap_fields_configurations(
  class PropertiesMetadata (line 81) | class PropertiesMetadata:
    method __init__ (line 95) | def __init__(self, fields_mapping_configurations: list[FieldMappingCon...
    method get_property_metadata_for_str (line 118) | def get_property_metadata_for_str(self, prop_path_str: str) -> Propert...
    method get_property_metadata (line 121) | def get_property_metadata(self, prop_path: list[str]) -> PropertyMetad...
    method __extract_fields (line 183) | def __extract_fields(self, property_path_str):
    method __get_property_path_str (line 201) | def __get_property_path_str(self, prop_path: list[str]) -> str:
    method __find_mapping_configuration (line 222) | def __find_mapping_configuration(self, prop_path_str: str):

FILE: keep/api/core/cel_to_sql/sql_providers/base.py
  class CelToSqlException (line 32) | class CelToSqlException(Exception):
  class CelToSqlResult (line 36) | class CelToSqlResult:
    method __init__ (line 38) | def __init__(self, sql: str, involved_fields: List[PropertyMetadataInf...
  class BaseCelToSqlProvider (line 43) | class BaseCelToSqlProvider:
    method __init__ (line 99) | def __init__(self, dialect: Dialect, properties_metadata: PropertiesMe...
    method convert_to_sql_str (line 105) | def convert_to_sql_str(self, cel: str) -> str:
    method convert_to_sql_str_v2 (line 108) | def convert_to_sql_str_v2(self, cel: str) -> CelToSqlResult:
    method get_order_by_expression (line 143) | def get_order_by_expression(self, sort_options: list[tuple[str, str]])...
    method get_field_expression (line 157) | def get_field_expression(self, cel_field: str) -> str:
    method literal_proc (line 180) | def literal_proc(self, value: Any) -> str:
    method _get_order_by_field (line 186) | def _get_order_by_field(self, cel_sort_by: str) -> str:
    method _build_sql_filter (line 189) | def _build_sql_filter(self, abstract_node: Node, stack: list[Node]) ->...
    method json_extract_as_text (line 224) | def json_extract_as_text(self, column: str, path: list[str]) -> str:
    method _json_contains_path (line 227) | def _json_contains_path(self, column: str, path: list[str]) -> str:
    method coalesce (line 232) | def coalesce(self, args):
    method cast (line 238) | def cast(self, expression_to_cast: str, to_type: DataType, force=False...
    method _visit_parentheses (line 241) | def _visit_parentheses(self, node: str) -> str:
    method _visit_logical_node (line 245) | def _visit_logical_node(self, logical_node: LogicalNode, stack: list[N...
    method _visit_logical_and (line 258) | def _visit_logical_and(self, left: str, right: str) -> str:
    method _visit_logical_or (line 261) | def _visit_logical_or(self, left: str, right: str) -> str:
    method _visit_comparison_node (line 267) | def _visit_comparison_node(self, comparison_node: ComparisonNode, stac...
    method _visit_equal (line 382) | def _visit_equal(self, first_operand: str, second_operand: str) -> str:
    method _visit_equal_for_array_datatype (line 388) | def _visit_equal_for_array_datatype(
    method _visit_not_equal (line 395) | def _visit_not_equal(self, first_operand: str, second_operand: str) ->...
    method _visit_greater_than (line 401) | def _visit_greater_than(self, first_operand: str, second_operand: str)...
    method _visit_greater_than_or_equal (line 404) | def _visit_greater_than_or_equal(self, first_operand: str, second_oper...
    method _visit_less_than (line 407) | def _visit_less_than(self, first_operand: str, second_operand: str) ->...
    method _visit_less_than_or_equal (line 410) | def _visit_less_than_or_equal(self, first_operand: str, second_operand...
    method _visit_in (line 413) | def _visit_in(self, first_operand: Node, array: list[ConstantNode], st...
    method _visit_in_for_array_datatype (line 481) | def _visit_in_for_array_datatype(
    method _visit_contains_method_calling (line 488) | def _visit_contains_method_calling(
    method _visit_starts_with_method_calling (line 495) | def _visit_starts_with_method_calling(
    method _visit_ends_with_method_calling (line 502) | def _visit_ends_with_method_calling(
    method _visit_constant_node (line 511) | def _visit_constant_node(
    method _get_data_type_to_convert (line 525) | def _get_data_type_to_convert(self, node: Node) -> DataType:
    method _visit_multiple_fields_node (line 544) | def _visit_multiple_fields_node(
    method _visit_member_access_node (line 560) | def _visit_member_access_node(self, member_access_node: MemberAccessNo...
    method _visit_property_access_node (line 568) | def _visit_property_access_node(self, property_access_node: PropertyAc...
    method _visit_index_property (line 574) | def _visit_index_property(self, property_path: str) -> str:
    method _visit_unary_node (line 579) | def _visit_unary_node(self, unary_node: UnaryNode, stack: list[Node]) ...
    method _visit_unary_not (line 589) | def _visit_unary_not(self, operand: Node, stack) -> str:
    method _visit_unary_has (line 592) | def _visit_unary_has(self, operand: Node, stack) -> str:
    method __convert_to_or (line 618) | def __convert_to_or(self, expressions: Node) -> LogicalNode:

FILE: keep/api/core/cel_to_sql/sql_providers/get_cel_to_sql_provider_for_dialect.py
  function get_cel_to_sql_provider (line 9) | def get_cel_to_sql_provider(
  function get_cel_to_sql_provider_for_dialect (line 15) | def get_cel_to_sql_provider_for_dialect(

FILE: keep/api/core/cel_to_sql/sql_providers/mysql.py
  class CelToMySqlProvider (line 20) | class CelToMySqlProvider(BaseCelToSqlProvider):
    method json_extract_as_text (line 22) | def json_extract_as_text(self, column: str, path: list[str]) -> str:
    method _json_contains_path (line 25) | def _json_contains_path(self, column: str, path: list[str]) -> str:
    method cast (line 29) | def cast(self, expression_to_cast: str, to_type, force=False):
    method _json_extract (line 57) | def _json_extract(self, column: str, path: list[str]) -> str:
    method get_order_by_expression (line 61) | def get_order_by_expression(self, sort_options: list[tuple[str, str]])...
    method _get_order_by_field (line 75) | def _get_order_by_field(self, cel_sort_by: str):
    method _visit_constant_node (line 99) | def _visit_constant_node(
    method _visit_contains_method_calling (line 121) | def _visit_contains_method_calling(
    method _visit_starts_with_method_calling (line 135) | def _visit_starts_with_method_calling(
    method _visit_ends_with_method_calling (line 149) | def _visit_ends_with_method_calling(
    method _visit_equal_for_array_datatype (line 163) | def _visit_equal_for_array_datatype(
    method _visit_in_for_array_datatype (line 185) | def _visit_in_for_array_datatype(

FILE: keep/api/core/cel_to_sql/sql_providers/postgresql.py
  class CelToPostgreSqlProvider (line 20) | class CelToPostgreSqlProvider(BaseCelToSqlProvider):
    method json_extract_as_text (line 22) | def json_extract_as_text(self, column: str, path: list[str]) -> str:
    method _json_contains_path (line 28) | def _json_contains_path(self, column: str, path: list[str]) -> str:
    method cast (line 32) | def cast(self, expression_to_cast: str, to_type: DataType, force=False):
    method get_field_expression (line 63) | def get_field_expression(self, cel_field):
    method _visit_constant_node (line 95) | def _visit_constant_node(
    method _visit_contains_method_calling (line 115) | def _visit_contains_method_calling(
    method _visit_starts_with_method_calling (line 125) | def _visit_starts_with_method_calling(
    method _visit_ends_with_method_calling (line 134) | def _visit_ends_with_method_calling(
    method _visit_equal_for_array_datatype (line 143) | def _visit_equal_for_array_datatype(
    method _visit_in_for_array_datatype (line 165) | def _visit_in_for_array_datatype(

FILE: keep/api/core/cel_to_sql/sql_providers/sqlite.py
  class CelToSqliteProvider (line 14) | class CelToSqliteProvider(BaseCelToSqlProvider):
    method json_extract_as_text (line 16) | def json_extract_as_text(self, column: str, path: list[str]) -> str:
    method _json_contains_path (line 20) | def _json_contains_path(self, column: str, path: list[str]) -> str:
    method cast (line 65) | def cast(self, expression_to_cast: str, to_type: DataType, force=False):
    method _visit_constant_node (line 93) | def _visit_constant_node(
    method _visit_property_path (line 113) | def _visit_property_path(self, property_path: str) -> str:
    method _visit_contains_method_calling (line 116) | def _visit_contains_method_calling(
    method _visit_starts_with_method_calling (line 126) | def _visit_starts_with_method_calling(
    method _visit_ends_with_method_calling (line 135) | def _visit_ends_with_method_calling(
    method _visit_equal_for_array_datatype (line 145) | def _visit_equal_for_array_datatype(
    method _visit_in_for_array_datatype (line 166) | def _visit_in_for_array_datatype(

FILE: keep/api/core/db.py
  function dispose_session (line 111) | def dispose_session():
  function existed_or_new_session (line 121) | def existed_or_new_session(session: Optional[Session] = None) -> Iterato...
  function get_session (line 133) | def get_session() -> Session:
  function get_session_sync (line 148) | def get_session_sync() -> Session:
  function __convert_to_uuid (line 158) | def __convert_to_uuid(value: str, should_raise: bool = False) -> UUID | ...
  function retry_on_db_error (line 167) | def retry_on_db_error(f):
  function create_workflow_execution (line 199) | def create_workflow_execution(
  function get_mapping_rule_by_id (line 262) | def get_mapping_rule_by_id(
  function get_extraction_rule_by_id (line 272) | def get_extraction_rule_by_id(
  function get_last_completed_execution (line 282) | def get_last_completed_execution(
  function get_timeouted_workflow_exections (line 299) | def get_timeouted_workflow_exections():
  function get_workflows_that_should_run (line 319) | def get_workflows_that_should_run():
  function update_workflow_by_id (line 448) | def update_workflow_by_id(
  function update_workflow_with_values (line 483) | def update_workflow_with_values(
  function is_equal_workflow_dicts (line 545) | def is_equal_workflow_dicts(a: dict, b: dict):
  function add_or_update_workflow (line 560) | def add_or_update_workflow(
  function get_or_create_dummy_workflow (line 654) | def get_or_create_dummy_workflow(tenant_id: str, session: Session | None...
  function get_workflow_to_alert_execution_by_workflow_execution_id (line 678) | def get_workflow_to_alert_execution_by_workflow_execution_id(
  function get_last_workflow_workflow_to_alert_executions (line 698) | def get_last_workflow_workflow_to_alert_executions(
  function get_last_workflow_execution_by_workflow_id (line 748) | def get_last_workflow_execution_by_workflow_id(
  function get_workflows_with_last_execution (line 773) | def get_workflows_with_last_execution(tenant_id: str) -> List[dict]:
  function get_all_workflows (line 817) | def get_all_workflows(tenant_id: str, exclude_disabled: bool = False) ->...
  function get_all_provisioned_workflows (line 833) | def get_all_provisioned_workflows(tenant_id: str):
  function get_all_provisioned_providers (line 845) | def get_all_provisioned_providers(tenant_id: str) -> List[Provider]:
  function get_all_workflows_yamls (line 855) | def get_all_workflows_yamls(tenant_id: str):
  function get_workflow_by_name (line 866) | def get_workflow_by_name(tenant_id: str, workflow_name: str):
  function get_workflow_by_id (line 878) | def get_workflow_by_id(tenant_id: str, workflow_id: str):
  function get_workflow_versions (line 890) | def get_workflow_versions(tenant_id: str, workflow_id: str):
  function get_workflow_version (line 906) | def get_workflow_version(tenant_id: str, workflow_id: str, revision: int):
  function update_provider_last_pull_time (line 922) | def update_provider_last_pull_time(tenant_id: str, provider_id: str):
  function get_installed_providers (line 947) | def get_installed_providers(tenant_id: str) -> List[Provider]:
  function get_consumer_providers (line 955) | def get_consumer_providers() -> List[Provider]:
  function finish_workflow_execution (line 964) | def finish_workflow_execution(tenant_id, workflow_id, execution_id, stat...
  function get_workflow_executions (line 1003) | def get_workflow_executions(
  function delete_workflow (line 1084) | def delete_workflow(tenant_id, workflow_id):
  function delete_workflow_by_provisioned_file (line 1097) | def delete_workflow_by_provisioned_file(tenant_id, provisioned_file):
  function get_workflow_id (line 1110) | def get_workflow_id(tenant_id, workflow_name):
  function push_logs_to_db (line 1124) | def push_logs_to_db(log_entries):
  function get_workflow_execution (line 1185) | def get_workflow_execution(
  function get_workflow_execution_with_logs (line 1207) | def get_workflow_execution_with_logs(
  function get_last_workflow_executions (line 1224) | def get_last_workflow_executions(tenant_id: str, limit=20):
  function get_workflow_executions_count (line 1240) | def get_workflow_executions_count(tenant_id: str):
  function add_audit (line 1252) | def add_audit(
  function _enrich_entity (line 1276) | def _enrich_entity(
  function batch_enrich (line 1360) | def batch_enrich(
  function enrich_entity (line 1457) | def enrich_entity(
  function count_alerts (line 1482) | def count_alerts(
  function get_enrichment (line 1515) | def get_enrichment(tenant_id, fingerprint, refresh=False):
  function get_enrichment_with_session (line 1521) | def get_enrichment_with_session(session, tenant_id, fingerprint, refresh...
  function get_enrichments (line 1558) | def get_enrichments(
  function get_alerts_with_filters (line 1577) | def get_alerts_with_filters(
  function query_alerts (line 1668) | def query_alerts(
  function get_started_at_for_alerts (line 1741) | def get_started_at_for_alerts(
  function get_last_alerts (line 1755) | def get_last_alerts(
  function get_alerts_by_fingerprint (line 1901) | def get_alerts_by_fingerprint(
  function get_all_alerts_by_fingerprints (line 1946) | def get_all_alerts_by_fingerprints(
  function get_alert_by_fingerprint_and_event_id (line 1959) | def get_alert_by_fingerprint_and_event_id(
  function get_alert_by_event_id (line 1973) | def get_alert_by_event_id(
  function get_alerts_by_ids (line 1987) | def get_alerts_by_ids(
  function get_previous_alert_by_fingerprint (line 2000) | def get_previous_alert_by_fingerprint(tenant_id: str, fingerprint: str) ...
  function get_alerts_by_status (line 2018) | def get_alerts_by_status(
  function get_api_key (line 2030) | def get_api_key(api_key: str, include_deleted: bool = False) -> TenantAp...
  function get_user_by_api_key (line 2040) | def get_user_by_api_key(api_key: str):
  function get_user (line 2046) | def get_user(username, password, update_sign_in=True):
  function get_users (line 2064) | def get_users(tenant_id=None):
  function delete_user (line 2074) | def delete_user(username):
  function user_exists (line 2088) | def user_exists(tenant_id, username):
  function create_user (line 2100) | def create_user(tenant_id, username, password, role):
  function update_user_last_sign_in (line 2117) | def update_user_last_sign_in(tenant_id, username):
  function update_user_role (line 2133) | def update_user_role(tenant_id, username, role):
  function save_workflow_results (line 2149) | def save_workflow_results(tenant_id, workflow_execution_id, workflow_res...
  function get_workflow_by_name (line 2173) | def get_workflow_by_name(tenant_id, workflow_name):
  function get_previous_execution_id (line 2186) | def get_previous_execution_id(tenant_id, workflow_id, workflow_execution...
  function create_rule (line 2206) | def create_rule(
  function update_rule (line 2255) | def update_rule(
  function get_rules (line 2309) | def get_rules(tenant_id, ids=None) -> list[Rule]:
  function create_alert (line 2327) | def create_alert(tenant_id, provider_type, provider_id, event, fingerpri...
  function delete_rule (line 2342) | def delete_rule(tenant_id, rule_id):
  function get_incident_for_grouping_rule (line 2359) | def get_incident_for_grouping_rule(
  function create_incident_for_grouping_rule (line 2395) | def create_incident_for_grouping_rule(
  function create_incident_for_topology (line 2430) | def create_incident_for_topology(
  function get_rule (line 2457) | def get_rule(tenant_id, rule_id):
  function get_rule_incidents_count_db (line 2465) | def get_rule_incidents_count_db(tenant_id):
  function get_rule_distribution (line 2476) | def get_rule_distribution(tenant_id, minute=False):
  function get_all_deduplication_rules (line 2540) | def get_all_deduplication_rules(tenant_id):
  function get_deduplication_rule_by_id (line 2550) | def get_deduplication_rule_by_id(tenant_id, rule_id: str):
  function get_custom_deduplication_rule (line 2564) | def get_custom_deduplication_rule(tenant_id, provider_id, provider_type):
  function create_deduplication_rule (line 2575) | def create_deduplication_rule(
  function update_deduplication_rule (line 2611) | def update_deduplication_rule(
  function delete_deduplication_rule (line 2655) | def delete_deduplication_rule(rule_id: str, tenant_id: str) -> bool:
  function create_deduplication_event (line 2674) | def create_deduplication_event(
  function get_all_deduplication_stats (line 2721) | def get_all_deduplication_stats(tenant_id):
  function get_last_alert_hashes_by_fingerprints (line 2821) | def get_last_alert_hashes_by_fingerprints(
  function update_key_last_used (line 2844) | def update_key_last_used(
  function get_linked_providers (line 2896) | def get_linked_providers(tenant_id: str) -> List[Tuple[str, str, datetim...
  function is_linked_provider (line 2922) | def is_linked_provider(tenant_id: str, provider_id: str) -> bool:
  function get_provider_distribution (line 2943) | def get_provider_distribution(
  function get_combined_workflow_execution_distribution (line 3078) | def get_combined_workflow_execution_distribution(
  function get_incidents_created_distribution (line 3156) | def get_incidents_created_distribution(
  function calc_incidents_mttr (line 3232) | def calc_incidents_mttr(tenant_id: str, timestamp_filter: TimeStampFilte...
  function get_presets (line 3329) | def get_presets(
  function get_db_preset_by_name (line 3358) | def get_db_preset_by_name(tenant_id: str, preset_name: str) -> Preset | ...
  function get_db_presets (line 3368) | def get_db_presets(tenant_id: str) -> List[Preset]:
  function get_all_presets_dtos (line 3378) | def get_all_presets_dtos(tenant_id: str) -> List[PresetDto]:
  function get_dashboards (line 3384) | def get_dashboards(tenant_id: str, email=None) -> List[Dict[str, Any]]:
  function create_dashboard (line 3406) | def create_dashboard(
  function update_dashboard (line 3423) | def update_dashboard(
  function delete_dashboard (line 3449) | def delete_dashboard(tenant_id, dashboard_id):
  function get_all_actions (line 3464) | def get_all_actions(tenant_id: str) -> List[Action]:
  function get_action (line 3472) | def get_action(tenant_id: str, action_id: str) -> Action:
  function create_action (line 3482) | def create_action(action: Action):
  function create_actions (line 3489) | def create_actions(actions: List[Action]):
  function delete_action (line 3496) | def delete_action(tenant_id: str, action_id: str) -> bool:
  function update_action (line 3510) | def update_action(
  function get_tenants (line 3528) | def get_tenants():
  function get_tenants_configurations (line 3534) | def get_tenants_configurations(only_with_config=False) -> dict:
  function update_preset_options (line 3556) | def update_preset_options(tenant_id: str, preset_id: str, options: dict)...
  function assign_alert_to_incident (line 3579) | def assign_alert_to_incident(
  function is_alert_assigned_to_incident (line 3588) | def is_alert_assigned_to_incident(
  function get_alert_audit (line 3604) | def get_alert_audit(
  function get_incidents_meta_for_tenant (line 3643) | def get_incidents_meta_for_tenant(tenant_id: str) -> dict:
  function apply_incident_filters (line 3765) | def apply_incident_filters(session: Session, filters: dict, query):
  function filter_query (line 3786) | def filter_query(session: Session, query, field, value):
  function enrich_incidents_with_alerts (line 3809) | def enrich_incidents_with_alerts(
  function enrich_alerts_with_incidents (line 3843) | def enrich_alerts_with_incidents(
  function get_incidents_by_alert_fingerprint (line 3877) | def get_incidents_by_alert_fingerprint(
  function get_last_incidents (line 3901) | def get_last_incidents(
  function get_incident_by_id (line 3984) | def get_incident_by_id(
  function create_incident_from_dto (line 4028) | def create_incident_from_dto(
  function create_incident_from_dict (line 4082) | def create_incident_from_dict(
  function update_incident_from_dto_by_id (line 4097) | def update_incident_from_dto_by_id(
  function get_incident_by_fingerprint (line 4149) | def get_incident_by_fingerprint(
  function delete_incident_by_id (line 4160) | def delete_incident_by_id(
  function get_incidents_count (line 4186) | def get_incidents_count(
  function get_incident_alerts_and_links_by_incident_id (line 4199) | def get_incident_alerts_and_links_by_incident_id(
  function get_incident_alerts_by_incident_id (line 4243) | def get_incident_alerts_by_incident_id(*args, **kwargs) -> tuple[List[Al...
  function get_future_incidents_by_incident_id (line 4254) | def get_future_incidents_by_incident_id(
  function get_int_severity (line 4274) | def get_int_severity(input_severity: int | str) -> int:
  function get_alerts_data_for_incident (line 4281) | def get_alerts_data_for_incident(
  function add_alerts_to_incident (line 4345) | def add_alerts_to_incident(
  function get_incident_unique_fingerprint_count (line 4535) | def get_incident_unique_fingerprint_count(
  function get_last_alerts_for_incidents (line 4550) | def get_last_alerts_for_incidents(
  function remove_alerts_to_incident_by_incident_id (line 4584) | def remove_alerts_to_incident_by_incident_id(
  class DestinationIncidentNotFound (line 4779) | class DestinationIncidentNotFound(Exception):
  function merge_incidents_to_id (line 4783) | def merge_incidents_to_id(
  function get_alerts_count (line 4850) | def get_alerts_count(
  function get_first_alert_datetime (line 4863) | def get_first_alert_datetime(
  function confirm_predicted_incident_by_id (line 4878) | def confirm_predicted_incident_by_id(
  function get_tenant_config (line 4914) | def get_tenant_config(tenant_id: str) -> dict:
  function write_tenant_config (line 4920) | def write_tenant_config(tenant_id: str, config: dict) -> None:
  function update_incident_summary (line 4929) | def update_incident_summary(
  function update_incident_name (line 4955) | def update_incident_name(tenant_id: str, incident_id: UUID, name: str) -...
  function update_incident_severity (line 4979) | def update_incident_severity(
  function get_topology_data_by_dynamic_matcher (line 5007) | def get_topology_data_by_dynamic_matcher(
  function get_tags (line 5022) | def get_tags(tenant_id):
  function create_tag (line 5028) | def create_tag(tag: Tag):
  function assign_tag_to_preset (line 5036) | def assign_tag_to_preset(tenant_id: str, tag_id: str, preset_id: str):
  function get_provider_by_name (line 5051) | def get_provider_by_name(tenant_id: str, provider_name: str) -> Provider:
  function get_provider_by_type_and_id (line 5061) | def get_provider_by_type_and_id(
  function bulk_upsert_alert_fields (line 5074) | def bulk_upsert_alert_fields(
  function get_alerts_fields (line 5173) | def get_alerts_fields(tenant_id: str) -> List[AlertField]:
  function change_incident_status_by_id (line 5181) | def change_incident_status_by_id(
  function get_workflow_executions_for_incident_or_alert (line 5205) | def get_workflow_executions_for_incident_or_alert(
  function is_all_alerts_resolved (line 5284) | def is_all_alerts_resolved(
  function is_all_alerts_in_status (line 5294) | def is_all_alerts_in_status(
  function is_last_incident_alert_resolved (line 5366) | def is_last_incident_alert_resolved(
  function is_first_incident_alert_resolved (line 5372) | def is_first_incident_alert_resolved(
  function is_edge_incident_alert_resolved (line 5378) | def is_edge_incident_alert_resolved(
  function get_alerts_metrics_by_provider (line 5420) | def get_alerts_metrics_by_provider(
  function get_or_create_external_ai_settings (line 5487) | def get_or_create_external_ai_settings(
  function update_extrnal_ai_settings (line 5510) | def update_extrnal_ai_settings(
  function get_table_class (line 5535) | def get_table_class(table_name: str) -> Type[SQLModel]:
  function get_resource_ids_by_resource_type (line 5564) | def get_resource_ids_by_resource_type(
  function get_or_creat_posthog_instance_id (line 5599) | def get_or_creat_posthog_instance_id(session: Optional[Session] = None):
  function get_activity_report (line 5619) | def get_activity_report(session: Optional[Session] = None):
  function get_last_alerts_by_fingerprints (line 5653) | def get_last_alerts_by_fingerprints(
  function get_last_alert_by_fingerprint (line 5668) | def get_last_alert_by_fingerprint(
  function set_last_alert (line 5686) | def set_last_alert(
  function set_maintenance_windows_trace (line 5779) | def set_maintenance_windows_trace(alert: Alert, maintenance_w: Maintenan...
  function get_provider_logs (line 5793) | def get_provider_logs(
  function enrich_incidents_with_enrichments (line 5810) | def enrich_incidents_with_enrichments(
  function get_error_alerts (line 5843) | def get_error_alerts(tenant_id: str, limit: int = 100) -> List[AlertRaw]:
  function dismiss_error_alerts (line 5857) | def dismiss_error_alerts(tenant_id: str, alert_id=None, dismissed_by=Non...
  function create_tenant (line 5880) | def create_tenant(tenant_name: str) -> str:
  function create_single_tenant_for_e2e (line 5915) | def create_single_tenant_for_e2e(tenant_id: str) -> None:
  function get_maintenance_windows_started (line 5942) | def get_maintenance_windows_started(session: Optional[Session] = None) -...
  function recover_prev_alert_status (line 5953) | def recover_prev_alert_status(alert: Alert, session: Optional[Session] =...

FILE: keep/api/core/db_on_start.py
  function try_create_single_tenant (line 52) | def try_create_single_tenant(tenant_id: str, create_default_user=True) -...
  function migrate_db (line 171) | def migrate_db():

FILE: keep/api/core/db_utils.py
  function __get_conn (line 32) | def __get_conn() -> pymysql.connections.Connection:
  function __get_conn_impersonate (line 51) | def __get_conn_impersonate() -> pymysql.connections.Connection:
  function dumps (line 118) | def dumps(_json) -> str:
  function create_db_engine (line 133) | def create_db_engine():
  function get_json_extract_field (line 179) | def get_json_extract_field(session, base_field, key):
  function get_aggreated_field (line 188) | def get_aggreated_field(session: Session, column_name: str, alias: str):
  class json_table (line 202) | class json_table(GenericFunction):
  function _compile_json_table (line 207) | def _compile_json_table(element, compiler, **kw):
  function get_or_create (line 221) | def get_or_create(
  function custom_serialize (line 274) | def custom_serialize(obj: Any) -> Any:

FILE: keep/api/core/demo_mode.py
  function get_or_create_topology (line 212) | def get_or_create_topology(keep_api_key, keep_api_url):
  function get_or_create_correlation_rules (line 265) | def get_or_create_correlation_rules(keep_api_key, keep_api_url):
  function get_installed_providers (line 282) | def get_installed_providers(keep_api_key, keep_api_url):
  function perform_demo_ai (line 291) | def perform_demo_ai(keep_api_key, keep_api_url):
  function safe_run_async_worker (line 394) | async def safe_run_async_worker(worker, *args, **kwargs):
  function simulate_alerts (line 427) | def simulate_alerts(*args, **kwargs):
  function simulate_alerts_async (line 435) | async def simulate_alerts_async(
  function launch_demo_mode_thread (line 576) | def launch_demo_mode_thread(
  function simulate_alerts_worker (line 616) | async def simulate_alerts_worker(worker_id, keep_api_key, rps=1):

FILE: keep/api/core/dependencies.py
  function extract_generic_body (line 26) | async def extract_generic_body(request: Request) -> dict | bytes | FormD...
  function get_pusher_client (line 52) | def get_pusher_client() -> Pusher | None:

FILE: keep/api/core/elastic.py
  class ElasticClient (line 15) | class ElasticClient:
    method __init__ (line 17) | def __init__(
    method alerts_index (line 95) | def alerts_index(self):
    method _construct_alert_dto_from_results (line 102) | def _construct_alert_dto_from_results(self, results):
    method run_query (line 125) | def run_query(self, query: str, limit: int = 1000):
    method search_alerts (line 165) | def search_alerts(self, query: str, limit: int) -> list[AlertDto]:
    method index_alert (line 203) | def index_alert(self, alert: AlertDto):
    method index_alerts (line 227) | def index_alerts(self, alerts: list[AlertDto]):
    method enrich_alert (line 262) | def enrich_alert(self, alert_fingerprint: str, alert_enrichments: dict):
    method drop_index (line 280) | def drop_index(self):

FILE: keep/api/core/facets.py
  function build_facet_selects (line 26) | def build_facet_selects(
  function map_facet_option_value (line 32) | def map_facet_option_value(value, data_type: DataType):
  function get_facet_options (line 57) | def get_facet_options(
  function create_facet (line 194) | def create_facet(tenant_id: str, entity_type, facet: CreateFacetDto) -> ...
  function delete_facet (line 229) | def delete_facet(tenant_id: str, entity_type: str, facet_id: str) -> bool:
  function get_facets (line 254) | def get_facets(

FILE: keep/api/core/facets_query_builder/base_facets_query_builder.py
  class BaseFacetsQueryBuilder (line 15) | class BaseFacetsQueryBuilder:
    method __init__ (line 20) | def __init__(
    method build_facets_data_query (line 26) | def build_facets_data_query(
    method build_facet_select (line 88) | def build_facet_select(self, entity_id_column, facet_key: str, facet_p...
    method build_facet_subquery (line 99) | def build_facet_subquery(
    method _get_select_for_column (line 151) | def _get_select_for_column(self, property_metadata: PropertyMetadataIn...
    method _cast_column (line 168) | def _cast_column(
    method _build_facet_subquery_for_json_array (line 175) | def _build_facet_subquery_for_json_array(
    method _handle_simple_mapping (line 182) | def _handle_simple_mapping(self, field_mapping: SimpleFieldMapping):
    method _coalesce (line 185) | def _coalesce(self, args: list):
    method _handle_json_mapping (line 191) | def _handle_json_mapping(self, field_mapping: JsonFieldMapping):

FILE: keep/api/core/facets_query_builder/get_facets_query_builder.py
  function get_facets_query_builder (line 14) | def get_facets_query_builder(
  function get_facets_query_builder_for_dialect (line 22) | def get_facets_query_builder_for_dialect(

FILE: keep/api/core/facets_query_builder/mysql.py
  class MySqlFacetsQueryBuilder (line 24) | class MySqlFacetsQueryBuilder(BaseFacetsQueryBuilder):
    method build_facet_subquery (line 26) | def build_facet_subquery(
    method _cast_column (line 46) | def _cast_column(self, column, data_type: DataType):
    method _get_select_for_column (line 58) | def _get_select_for_column(self, property_metadata: PropertyMetadataIn...
    method _build_facet_subquery_for_json_array (line 65) | def _build_facet_subquery_for_json_array(
    method _handle_json_mapping (line 81) | def _handle_json_mapping(self, field_mapping: JsonFieldMapping):

FILE: keep/api/core/facets_query_builder/postgresql.py
  class PostgreSqlFacetsQueryBuilder (line 17) | class PostgreSqlFacetsQueryBuilder(BaseFacetsQueryBuilder):
    method _get_select_for_column (line 19) | def _get_select_for_column(self, property_metadata: PropertyMetadataIn...
    method build_facet_subquery (line 40) | def build_facet_subquery(
    method _cast_column (line 60) | def _cast_column(self, column, data_type: DataType):
    method _build_facet_subquery_for_json_array (line 78) | def _build_facet_subquery_for_json_array(
    method _handle_json_mapping (line 94) | def _handle_json_mapping(self, field_mapping: JsonFieldMapping):

FILE: keep/api/core/facets_query_builder/sqlite.py
  class SqliteFacetsHandler (line 14) | class SqliteFacetsHandler(BaseFacetsQueryBuilder):
    method _get_select_for_column (line 16) | def _get_select_for_column(self, property_metadata: PropertyMetadataIn...
    method _cast_column (line 23) | def _cast_column(self, column, data_type: DataType):
    method _build_facet_subquery_for_json_array (line 35) | def _build_facet_subquery_for_json_array(
    method _handle_json_mapping (line 45) | def _handle_json_mapping(self, field_mapping: JsonFieldMapping):

FILE: keep/api/core/facets_query_builder/utils.py
  function get_facet_key (line 4) | def get_facet_key(facet_property_path: str, filter_cel, facet_cel: str) ...

FILE: keep/api/core/incidents.py
  function __build_base_incident_query (line 192) | def __build_base_incident_query(
  function __build_last_incidents_total_count_query (line 309) | def __build_last_incidents_total_count_query(
  function __build_last_incidents_query (line 377) | def __build_last_incidents_query(
  function get_last_incidents_by_cel (line 464) | def get_last_incidents_by_cel(
  function get_incident_facets_data (line 549) | def get_incident_facets_data(
  function get_incident_facets (line 609) | def get_incident_facets(
  function get_incident_potential_facet_fields (line 648) | def get_incident_potential_facet_fields(tenant_id: str) -> list[str]:

FILE: keep/api/core/report_uptime.py
  function report_uptime_to_posthog (line 21) | async def report_uptime_to_posthog():
  function launch_uptime_reporting_thread (line 55) | def launch_uptime_reporting_thread() -> threading.Thread | None:

FILE: keep/api/core/tenant_configuration.py
  class TenantConfiguration (line 10) | class TenantConfiguration:
    class _TenantConfiguration (line 13) | class _TenantConfiguration:
      method __init__ (line 15) | def __init__(self):
      method _load_tenant_configurations (line 23) | def _load_tenant_configurations(self):
      method _reload_if_needed (line 35) | def _reload_if_needed(self):
      method get_configuration (line 45) | def get_configuration(self, tenant_id, config_name=None):
    method __new__ (line 70) | def __new__(cls):

FILE: keep/api/core/tracer.py
  class KeepSampler (line 11) | class KeepSampler(sampling.Sampler):
    method __init__ (line 12) | def __init__(self, parent_sampler=None):
    method should_sample (line 26) | def should_sample(
    method get_description (line 45) | def get_description(self):

FILE: keep/api/core/workflows.py
  function __build_workflow_executions_query (line 108) | def __build_workflow_executions_query(tenant_id: str):
  function build_workflow_executions_query (line 134) | def build_workflow_executions_query(
  function __build_base_query (line 157) | def __build_base_query(
  function build_workflows_total_count_query (line 200) | def build_workflows_total_count_query(tenant_id: str, cel: str):
  function build_workflows_query (line 215) | def build_workflows_query(
  class WorkflowWithLastExecutions (line 253) | class WorkflowWithLastExecutions(TypedDict):
  function get_workflows_with_last_executions_v2 (line 261) | def get_workflows_with_last_executions_v2(
  function get_workflow_facets (line 338) | def get_workflow_facets(
  function get_workflow_facets_data (line 361) | def get_workflow_facets_data(
  function get_workflow_potential_facet_fields (line 396) | def get_workflow_potential_facet_fields(tenant_id: str) -> list[str]:

FILE: keep/api/custom_worker.py
  class CustomUvicornWorker (line 4) | class CustomUvicornWorker(UvicornWorker):

FILE: keep/api/logging.py
  function get_gunicorn_log_level (line 31) | def get_gunicorn_log_level():
  class WorkflowContextFilter (line 57) | class WorkflowContextFilter(logging.Filter):
    method filter (line 64) | def filter(self, record):
  class WorkflowDBHandler (line 109) | class WorkflowDBHandler(logging.Handler):
    method __init__ (line 110) | def __init__(self, flush_interval: int = 2):
    method _timer_run (line 125) | def _timer_run(self):
    method close (line 132) | def close(self):
    method emit (line 137) | def emit(self,
Copy disabled (too large) Download .json
Condensed preview — 2212 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (10,013K chars).
[
  {
    "path": ".cursor/rules/keep-ui-react-typescript.mdc",
    "chars": 3772,
    "preview": "---\ndescription: \nglobs: \nalwaysApply: true\n---\n---\ndescription: Rules for writing frontend code at Keep (React + Typesc"
  },
  {
    "path": ".cursor/rules/keep-ui-tests.mdc",
    "chars": 516,
    "preview": "---\ndescription: \nglobs: \nalwaysApply: true\n---\n---\ndescription: Rules and guidelines for writing and running React test"
  },
  {
    "path": ".dockerignore",
    "chars": 97,
    "preview": "docs/*\nkeep-ui/node_modules\nkeep-ui/.next/*\nkeep-ui/.env.local\n.venv/\n.vercel/\n.vscode/\n.github/\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 544,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: \"[🐛 Bug]: \"\nlabels: \"\"\nassignees: \"\"\n---\n\n**Descri"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 419,
    "preview": "blank_issues_enabled: true\n\ncontact_links:\n  - name: Support\n    url: https://github.com/keephq/keep/discussions\n    abo"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/documentation.md",
    "chars": 244,
    "preview": "---\nname: Documentation issue\nabout: Any issue related with Keep's documentation\ntitle: \"[📃 Docs]: \"\nlabels: \"Documentat"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 607,
    "preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: \"[➕ Feature]: \"\nlabels: \"\"\nassignees: \"\"\n---\n\n*"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/new_provider_request.md",
    "chars": 484,
    "preview": "---\nname: New provider request\nabout: Suggest a new provider for keep\ntitle: \"[🔌 Provider]: \"\nlabels: \"Provider\"\nassigne"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/use_case.md",
    "chars": 212,
    "preview": "---\nname: Use case\nabout: Tell us how you use Keep and we will add it to the docs.\ntitle: ''\nlabels: ''\nassignees: ''\n\n-"
  },
  {
    "path": ".github/workflows/auto-release.yml",
    "chars": 1420,
    "preview": "name: Auto Release on Version Change\n\non:\n  push:\n    branches:\n      - main\n    paths:\n      - \"pyproject.toml\"\n\njobs:\n"
  },
  {
    "path": ".github/workflows/auto-resolve-keep.yml",
    "chars": 4048,
    "preview": "name: Auto resolve Keep incident/alert\n\non:\n  workflow_dispatch:\n    inputs:\n      incident_id:\n        description: \"Ke"
  },
  {
    "path": ".github/workflows/but-to-project.yml",
    "chars": 395,
    "preview": "name: Add bugs to project board\n\non:\n  issues:\n    types:\n      - labeled\n\njobs:\n  add-to-project:\n    name: Add bug to "
  },
  {
    "path": ".github/workflows/developer-onboarding-notification.yml",
    "chars": 5339,
    "preview": "name: Celebrating Contributions\n\non:\n  pull_request_target:\n    types: [closed]\n\npermissions:\n  pull-requests: write\n\njo"
  },
  {
    "path": ".github/workflows/lint-pr.yml",
    "chars": 2005,
    "preview": "name: \"Lint PR\"\n\non:\n  pull_request_target:\n    types:\n      - opened\n      - edited\n      - synchronize\n      - reopene"
  },
  {
    "path": ".github/workflows/release-workflow-schema.yml",
    "chars": 5790,
    "preview": "name: Release JSON Schema\n\non:\n  push:\n    branches:\n      - main\n    paths:\n      - \".github/workflows/release-workflow"
  },
  {
    "path": ".github/workflows/release.yml",
    "chars": 1758,
    "preview": "name: Keep Release\n\non:\n  workflow_dispatch:\n\njobs:\n  release:\n    runs-on: ubuntu-latest\n    concurrency: release\n    p"
  },
  {
    "path": ".github/workflows/run-e2e-tests.yml",
    "chars": 14407,
    "preview": "on:\n  workflow_call:\n    inputs:\n      db-type:\n        required: true\n        type: string\n      redis_enabled:\n       "
  },
  {
    "path": ".github/workflows/sync-keep-workflows.yml",
    "chars": 1040,
    "preview": "# A workflow that sync Keep workflows from a directory\nname: \"Sync Keep Workflows\"\n\non:\n    workflow_dispatch:\n        i"
  },
  {
    "path": ".github/workflows/test-docs.yml",
    "chars": 1814,
    "preview": "name: Test docs\non:\n  push:\n    paths:\n      - 'keep/providers/**'\n      - 'docs/**'\n      - 'examples/**'\n  pull_reques"
  },
  {
    "path": ".github/workflows/test-pr-e2e.yml",
    "chars": 13117,
    "preview": "name: Tests (E2E)\n\non:\n  workflow_dispatch:\n  pull_request:\n    paths:\n      - \"keep/**\"\n      - \"keep-ui/**\"\n      - \"t"
  },
  {
    "path": ".github/workflows/test-pr-integrations.yml",
    "chars": 3188,
    "preview": "name: Integration Tests\non:\n  push:\n    branches:\n      - main\n    paths:\n      - \"keep/**\"\n      - \"tests/**\"\n  pull_re"
  },
  {
    "path": ".github/workflows/test-pr-ut-ui.yml",
    "chars": 1262,
    "preview": "name: Frontend Tests\non:\n  push:\n    branches:\n      - main\n    paths:\n      - \"keep-ui/**\"\n  pull_request:\n    paths:\n "
  },
  {
    "path": ".github/workflows/test-pr-ut.yml",
    "chars": 1701,
    "preview": "name: Unit Tests\non:\n  push:\n    branches:\n      - main\n    paths:\n      - \"keep/**\"\n      - \"tests/**\"\n  pull_request:\n"
  },
  {
    "path": ".github/workflows/test-workflow-examples.yml",
    "chars": 2176,
    "preview": "name: Test workflow examples\non:\n  push:\n    paths:\n      - 'keep/providers/**'\n      - 'examples/workflows/**'\n      - "
  },
  {
    "path": ".gitignore",
    "chars": 4018,
    "preview": "# .DS_STORE\n.DS_Store\n**/.DS_Store\n\n# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C exten"
  },
  {
    "path": ".pre-commit-config.yaml",
    "chars": 1408,
    "preview": "repos:\n  - repo: local\n    hooks:\n      - id: black\n        name: black\n        entry: black\n        language: system\n  "
  },
  {
    "path": ".python-version",
    "chars": 7,
    "preview": "3.11.1\n"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 1146,
    "preview": "# CHANGELOG\n{% if context.history.unreleased | length > 0 %}\n\n{# UNRELEASED #}\n## Unreleased\n{% for type_, commits in co"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 2229,
    "preview": "# Contributing to Keep\nWe love your input! We want to make contributing to this project as easy and transparent as possi"
  },
  {
    "path": "LICENSE",
    "chars": 1385,
    "preview": "Copyright (c) 2024 Keep\n\nPortions of this software are licensed as follows:\n\n* All content that resides under the \"ee/\" "
  },
  {
    "path": "README.md",
    "chars": 37721,
    "preview": "<div align=\"center\">\n    <img src=\"/assets/keep.png?raw=true\" width=\"86\">\n</div>\n\n<h1 align=\"center\">The open-source AIO"
  },
  {
    "path": "docker/Dockerfile.api",
    "chars": 2272,
    "preview": "FROM python:3.13.5-alpine as base\n\n# Install bash and runtime dependencies for grpc\nRUN apk add --no-cache bash libstdc+"
  },
  {
    "path": "docker/Dockerfile.cli",
    "chars": 535,
    "preview": "FROM python:3.11.6-slim as base\n\nENV PYTHONFAULTHANDLER=1 \\\n    PYTHONHASHSEED=random \\\n    PYTHONUNBUFFERED=1\n\nWORKDIR "
  },
  {
    "path": "docker/Dockerfile.dev.api",
    "chars": 849,
    "preview": "FROM python:3.11.6-slim as base\n\nENV PYTHONFAULTHANDLER=1 \\\n    PYTHONHASHSEED=random \\\n    PYTHONUNBUFFERED=1\n\nWORKDIR "
  },
  {
    "path": "docker/Dockerfile.dev.ui",
    "chars": 708,
    "preview": "# Use node alpine as it's a small node image\nFROM node:alpine\n\n# Create the directory on the node image\n# where our Next"
  },
  {
    "path": "docker/Dockerfile.ui",
    "chars": 2487,
    "preview": "FROM node:20-alpine AS base\n\n# Install dependencies only when needed\nFROM base AS deps\n# Check https://github.com/nodejs"
  },
  {
    "path": "docker-compose-with-arq.yml",
    "chars": 1211,
    "preview": "services:\n  keep-frontend:\n    extends:\n      file: docker-compose.common.yml\n      service: keep-frontend-common\n    im"
  },
  {
    "path": "docker-compose-with-auth.yml",
    "chars": 827,
    "preview": "services:\n  keep-frontend:\n    extends:\n      file: docker-compose.common.yml\n      service: keep-frontend-common\n    im"
  },
  {
    "path": "docker-compose-with-otel.yaml",
    "chars": 3195,
    "preview": "services:\n  loki:\n    image: grafana/loki:latest\n    profiles:\n      - otel\n\n    ports:\n      - \"3100:3100\"\n    command:"
  },
  {
    "path": "docker-compose.common.yml",
    "chars": 1356,
    "preview": "services:\n  keep-frontend-common:\n    ports:\n      - \"3000:3000\"\n    environment:\n      - NEXTAUTH_SECRET=secret\n      -"
  },
  {
    "path": "docker-compose.dev.yml",
    "chars": 719,
    "preview": "services:\n  keep-frontend-dev:\n    extends:\n      file: docker-compose.common.yml\n      service: keep-frontend-common\n  "
  },
  {
    "path": "docker-compose.yml",
    "chars": 1493,
    "preview": "services:\n  keep-frontend:\n    extends:\n      file: docker-compose.common.yml\n      service: keep-frontend-common\n    im"
  },
  {
    "path": "docs/README.md",
    "chars": 115,
    "preview": "How to run docs locally:\n\n```\nnpm i -g mintlify\nmintlify dev\n```\n\nRead more: https://mintlify.com/docs/development\n"
  },
  {
    "path": "docs/alertevaluation/examples/victoriametricsmulti.mdx",
    "chars": 2305,
    "preview": "---\ntitle: \"VictoriaMetrics Multi Alert Example\"\n---\n\nThis example demonstrates a simple CPU usage multi-alert based on "
  },
  {
    "path": "docs/alertevaluation/examples/victoriametricssingle.mdx",
    "chars": 1751,
    "preview": "---\ntitle: \"VictoriaMetrics Single Alert Example\"\n---\n\nThis example demonstrates a simple CPU usage alert based on a met"
  },
  {
    "path": "docs/alertevaluation/overview.mdx",
    "chars": 2345,
    "preview": "---\ntitle: \"Overview\"\n---\n\nThe Keep Alert Evaluation Engine is a flexible system that enables you to create alerts based"
  },
  {
    "path": "docs/alerts/actionmenu.mdx",
    "chars": 1798,
    "preview": "---\ntitle: \"Action Menu\"\n---\n\nThe Action Menu in Keep provides quick access to common actions that can be performed on a"
  },
  {
    "path": "docs/alerts/overview.mdx",
    "chars": 721,
    "preview": "---\ntitle: \"Overview\"\n---\n\n**Alert Management** empowers teams to effectively manage, monitor, and act on critical alert"
  },
  {
    "path": "docs/alerts/presets.mdx",
    "chars": 3589,
    "preview": "---\ntitle: \"Customized Presets\"\n---\n\n\n<Tip>\n\nYou can think of a preset like a \"Slack Channel\" for your alerts - a logica"
  },
  {
    "path": "docs/alerts/sidebar.mdx",
    "chars": 1692,
    "preview": "---\ntitle: \"Alert Sidebar\"\n---\n\nThe Alert Sidebar in Keep provides a detailed view of a selected alert, offering in-dept"
  },
  {
    "path": "docs/alerts/sound.mdx",
    "chars": 796,
    "preview": "---\r\ntitle: \"Sound Notifications\"\r\n---\r\n\r\nSound notifications ensure you never miss important updates or alerts.\r\n\r\n## H"
  },
  {
    "path": "docs/alerts/table.mdx",
    "chars": 2686,
    "preview": "---\ntitle: \"Alert Table\"\n---\n\nThe Alert Table is the central interface for viewing and managing alerts in Keep. It provi"
  },
  {
    "path": "docs/applications/github.mdx",
    "chars": 8210,
    "preview": "---\ntitle: \"GitHub Application\"\nsidebarTitle: \"GitHub\"\ndescription: \"The Keep GitHub Application is a powerful tool that"
  },
  {
    "path": "docs/authentication/okta.md",
    "chars": 8781,
    "preview": "# Okta Integration Guide\n\nThis document provides comprehensive information about the Okta integration in Keep, including"
  },
  {
    "path": "docs/cli/commands/alert-enrich.mdx",
    "chars": 362,
    "preview": "---\nsidebarTitle: \"keep alert enrich\"\n---\n\nEnrich an alert.\n\n## Usage\n\n```\nUsage: keep alert enrich [OPTIONS] [PARAMS].."
  },
  {
    "path": "docs/cli/commands/alert-get.mdx",
    "chars": 244,
    "preview": "---\nsidebarTitle: \"keep alert get\"\n---\n\nGet an alert.\n\n## Usage\n\n```\nUsage: keep alert get [OPTIONS] FINGERPRINT\n```\n\n##"
  },
  {
    "path": "docs/cli/commands/alert-list.mdx",
    "chars": 792,
    "preview": "---\nsidebarTitle: \"keep alert list\"\n---\n\nList alerts.\n\n## Usage\n\n```\nUsage: keep alert list [OPTIONS]\n```\n\n## Options\n* "
  },
  {
    "path": "docs/cli/commands/cli-alert.mdx",
    "chars": 404,
    "preview": "\n# cli alert\n\nManage alerts.\n\n## Usage\n\n```\nUsage: cli alert [OPTIONS] COMMAND [ARGS]...\n```\n\n## Options\n* `help`:\n  * T"
  },
  {
    "path": "docs/cli/commands/cli-api.mdx",
    "chars": 495,
    "preview": "---\ntitle: \"api\"\nsidebarTitle: \"keep api\"\n---\n\nStart the API.\n\n## Usage\n\n```\nUsage: keep api [OPTIONS]\n```\n\n## Options\n*"
  },
  {
    "path": "docs/cli/commands/cli-config-new.mdx",
    "chars": 876,
    "preview": "---\nsidebarTitle: \"keep config new\"\n---\n\nCreate new config.\n\n## Usage\n\n```\nUsage: keep config new [OPTIONS]...\n```\n\n## O"
  },
  {
    "path": "docs/cli/commands/cli-config-show.mdx",
    "chars": 366,
    "preview": "---\nsidebarTitle: \"keep config show\"\n---\n\nShow keep configuration.\n\n## Usage\n\n```\nUsage: keep config show [OPTIONS]...\n`"
  },
  {
    "path": "docs/cli/commands/cli-config.mdx",
    "chars": 464,
    "preview": "---\ntitle: \"config\"\nsidebarTitle: \"keep config\"\n---\n\nSet keep configuration.\n\n## Usage\n\n```\nUsage: keep config [OPTIONS]"
  },
  {
    "path": "docs/cli/commands/cli-provider.mdx",
    "chars": 409,
    "preview": "\n# cli provider\n\nManage providers.\n\n## Usage\n\n```\nUsage: cli provider [OPTIONS] COMMAND [ARGS]...\n```\n\n## Options\n* `hel"
  },
  {
    "path": "docs/cli/commands/cli-run.mdx",
    "chars": 2033,
    "preview": "---\ntitle: \"run\"\nsidebarTitle: \"keep run\"\n---\n\nRun the alert.\n\n## Usage\n\n```\nUsage: keep run [OPTIONS]\n```\n\n## Options\n*"
  },
  {
    "path": "docs/cli/commands/cli-version.mdx",
    "chars": 368,
    "preview": "---\ntitle: \"version\"\nsidebarTitle: \"keep version\"\n---\n\nGet the library version.\n\n## Usage\n\n```\nUsage: keep version [OPTI"
  },
  {
    "path": "docs/cli/commands/cli-whoami.mdx",
    "chars": 364,
    "preview": "---\ntitle: \"whoami\"\nsidebarTitle: \"keep whoami\"\n---\n\nVerify the api key auth.\n\n## Usage\n\n```\nUsage: keep whoami [OPTIONS"
  },
  {
    "path": "docs/cli/commands/cli-workflow.mdx",
    "chars": 514,
    "preview": "\n# cli workflow\n\nManage workflows.\n\n## Usage\n\n```\nUsage: cli workflow [OPTIONS] COMMAND [ARGS]...\n```\n\n## Options\n* `hel"
  },
  {
    "path": "docs/cli/commands/cli.mdx",
    "chars": 1115,
    "preview": "\n# cli\n\nRun Keep CLI.\n\n## Usage\n\n```\nUsage: cli [OPTIONS] COMMAND [ARGS]...\n```\n\n## Options\n* `verbose`:\n  * Type: IntRa"
  },
  {
    "path": "docs/cli/commands/extraction-create.mdx",
    "chars": 2299,
    "preview": "---\nsidebarTitle: \"keep extraction create\"\n---\n\nCreate a extraction rule.\n\n## Usage\n\n```\nUsage: keep extraction create ["
  },
  {
    "path": "docs/cli/commands/extraction-delete.mdx",
    "chars": 645,
    "preview": "---\nsidebarTitle: \"keep extraction delete\"\n---\n\nDelete an extraction with a specified ID.\n\n## Usage\n\n```\nUsage: keep ext"
  },
  {
    "path": "docs/cli/commands/extractions-list.mdx",
    "chars": 378,
    "preview": "---\nsidebarTitle: \"keep extraction list\"\n---\n\nList extractions.\n\n## Usage\n\n```\nUsage: keep extraction list [OPTIONS]\n```"
  },
  {
    "path": "docs/cli/commands/mappings-create.mdx",
    "chars": 1677,
    "preview": "---\nsidebarTitle: \"keep mappings create\"\n---\n\nCreate a mapping rule.\n\n## Usage\n\n```\nUsage: keep mappings create [OPTIONS"
  },
  {
    "path": "docs/cli/commands/mappings-delete.mdx",
    "chars": 608,
    "preview": "---\nsidebarTitle: \"keep mappings delete\"\n---\n\nDelete a mapping with a specified ID.\n\n## Usage\n\n```\nUsage: keep mappings "
  },
  {
    "path": "docs/cli/commands/mappings-list.mdx",
    "chars": 359,
    "preview": "---\nsidebarTitle: \"keep mappings list\"\n---\n\nList mappings.\n\n## Usage\n\n```\nUsage: keep mappings [OPTIONS]\n```\n\nList mappi"
  },
  {
    "path": "docs/cli/commands/provider-connect.mdx",
    "chars": 390,
    "preview": "---\nsidebarTitle: \"keep provider connect\"\n---\n\nConnect a provider.\n\n## Usage\n\n```\nUsage: keep provider connect [OPTIONS]"
  },
  {
    "path": "docs/cli/commands/provider-delete.mdx",
    "chars": 271,
    "preview": "---\nsidebarTitle: \"keep provider delete\"\n---\n\nDelete a provider.\n\n## Usage\n\n```\nUsage: keep provider delete [OPTIONS] [P"
  },
  {
    "path": "docs/cli/commands/provider-list.mdx",
    "chars": 535,
    "preview": "---\nsidebarTitle: \"keep provider list\"\n---\n\nList providers.\n\n## Usage\n\n```\nUsage: keep provider list [OPTIONS]\n```\n\n## O"
  },
  {
    "path": "docs/cli/commands/runs-list.mdx",
    "chars": 386,
    "preview": "---\nsidebarTitle: \"keep workflow runs list\"\n---\n\nList workflow executions.\n\n## Usage\n\n```\nUsage: keep workflow runs list"
  },
  {
    "path": "docs/cli/commands/runs-logs.mdx",
    "chars": 338,
    "preview": "---\nsidebarTitle: \"keep workflow runs logs\"\n---\n\nGet workflow execution logs.\n\n## Usage\n\n```\nUsage: keep workflow runs l"
  },
  {
    "path": "docs/cli/commands/workflow-apply.mdx",
    "chars": 519,
    "preview": "---\nsidebarTitle: \"keep workflow apply\"\n---\n\n\nApply a workflow.\n\n## Usage\n\n```\nUsage: keep workflow apply [OPTIONS]\n```\n"
  },
  {
    "path": "docs/cli/commands/workflow-list.mdx",
    "chars": 351,
    "preview": "---\nsidebarTitle: \"keep workflow list\"\n---\n\nList workflows.\n\n## Usage\n\n```\nUsage: keep workflow list [OPTIONS]\n```\n\n## O"
  },
  {
    "path": "docs/cli/commands/workflow-run.mdx",
    "chars": 858,
    "preview": "---\nsidebarTitle: \"keep workflow run\"\n---\n\nRun a workflow with a specified ID and fingerprint.\n\n## Usage\n\n```\nUsage: kee"
  },
  {
    "path": "docs/cli/commands/workflow-runs.mdx",
    "chars": 493,
    "preview": "---\nsidebarTitle: \"keep workflow runs\"\n---\n\nManage workflows executions.\n\n## Usage\n\n```\nUsage: cli workflow runs [OPTION"
  },
  {
    "path": "docs/cli/github-actions.mdx",
    "chars": 2003,
    "preview": "---\ntitle: \"Sync Keep Workflows With Github Action\"\n---\n\nThis documentation provides a detailed guide on how to use the "
  },
  {
    "path": "docs/cli/installation.mdx",
    "chars": 2394,
    "preview": "---\ntitle: \"Installation\"\n---\n<Info>Missing an installation? submit a <a href=\"https://github.com/keephq/keep/issues/new"
  },
  {
    "path": "docs/cli/overview.mdx",
    "chars": 442,
    "preview": "---\ntitle: \"Overview\"\n---\n\nKeep CLI allow you to manage Keep from CLI.\n\nStart by [installing](/cli/installation) Keep CL"
  },
  {
    "path": "docs/deployment/authentication/auth0-auth.mdx",
    "chars": 1834,
    "preview": "---\ntitle: \"Auth0 Authentication\"\n---\n\n<Tip>\nKeep Cloud: ✅ <br/>\nKeep Enterprise On-Premises: ✅ <br/>\nKeep Open Source: "
  },
  {
    "path": "docs/deployment/authentication/azuread-auth.mdx",
    "chars": 6904,
    "preview": "---\ntitle: \"Azure AD Authentication\"\n---\n\n<Tip>\nKeep Cloud: ✅ <br/>\nKeep Enterprise On-Premises: ✅ <br/>\nKeep Open Sourc"
  },
  {
    "path": "docs/deployment/authentication/db-auth.mdx",
    "chars": 1312,
    "preview": "---\ntitle: \"DB Authentication\"\n---\n\nFor applications requiring user management and authentication, Keep supports basic a"
  },
  {
    "path": "docs/deployment/authentication/keycloak-auth.mdx",
    "chars": 2877,
    "preview": "---\ntitle: \"Keycloak Authentication\"\n---\n\n<Tip>\nKeep Cloud: ✅ <br/>\nKeep Enterprise On-Premises: ✅ <br/>\nKeep Open Sourc"
  },
  {
    "path": "docs/deployment/authentication/no-auth.mdx",
    "chars": 947,
    "preview": "---\ntitle: \"No Authentication\"\n---\n<Warning>Using this configuration in production is not secure and strongly discourage"
  },
  {
    "path": "docs/deployment/authentication/oauth2-proxy-gitlab.mdx",
    "chars": 8515,
    "preview": "---\ntitle: \"Example: OAuth2‑Proxy + Keep + GitLab SSO\"\n---\n\nA **step‑by‑step cookbook** for adding single‑sign‑on to [Ke"
  },
  {
    "path": "docs/deployment/authentication/oauth2proxy-auth.mdx",
    "chars": 1703,
    "preview": "---\ntitle: \"OAuth2Proxy Authentication\"\n---\n\n<Tip>\nKeep Cloud: ✅ <br/>\nKeep Enterprise On-Premises: ✅ <br/>\nKeep Open So"
  },
  {
    "path": "docs/deployment/authentication/okta-auth.mdx",
    "chars": 2962,
    "preview": "---\ntitle: \"Okta Authentication\"\n---\n\nThis document provides comprehensive information about the Okta integration in Kee"
  },
  {
    "path": "docs/deployment/authentication/onelogin-auth.mdx",
    "chars": 2708,
    "preview": "---\ntitle: \"OneLogin Authentication\"\n---\n\nThis document provides comprehensive information about the OneLogin integratio"
  },
  {
    "path": "docs/deployment/authentication/overview.mdx",
    "chars": 4559,
    "preview": "---\ntitle: \"Overview\"\n---\n\n<Tip>For every authentication-related question or issue, please join our [Slack](https://slac"
  },
  {
    "path": "docs/deployment/configuration.mdx",
    "chars": 30816,
    "preview": "---\ntitle: \"Configuration\"\nsidebarTitle: \"Configuration\"\n---\n\n## Background\n\nKeep is highly configurable through environ"
  },
  {
    "path": "docs/deployment/docker.mdx",
    "chars": 2374,
    "preview": "---\ntitle: \"Docker\"\nsidebarTitle: \"Docker\"\n---\n\n### Spin up Keep with docker-compose latest images\nThe easiest way to st"
  },
  {
    "path": "docs/deployment/ecs.mdx",
    "chars": 7293,
    "preview": "---\ntitle: \"AWS ECS\"\nsidebarTitle: \"AWS ECS\"\n---\n\n## Step 1: Login to AWS Console\n- Open your web browser and navigate t"
  },
  {
    "path": "docs/deployment/kubernetes/architecture.mdx",
    "chars": 9648,
    "preview": "---\ntitle: \"Architecture\"\nsidebarTitle: \"Architecture\"\n---\n\n\n## High Level Architecture\nKeep architecture composes of tw"
  },
  {
    "path": "docs/deployment/kubernetes/installation.mdx",
    "chars": 6226,
    "preview": "---\ntitle: \"Installation\"\nsidebarTitle: \"Installation\"\n---\n\n<Tip>\nThe recommended way to install Keep on Kubernetes is v"
  },
  {
    "path": "docs/deployment/kubernetes/openshift.mdx",
    "chars": 427,
    "preview": "---\ntitle: \"Openshift\"\nsidebarTitle: \"Openshift\"\n---\n\nKeep's Helm Chart also supports Openshift installation.\n\nSimply fo"
  },
  {
    "path": "docs/deployment/kubernetes/overview.mdx",
    "chars": 824,
    "preview": "---\ntitle: \"Overview\"\nsidebarTitle: \"Overview\"\n---\n\n<Tip> If you need help deploying Keep on Kubernetes or have any feed"
  },
  {
    "path": "docs/deployment/local-llm/keep-with-litellm.mdx",
    "chars": 2872,
    "preview": "---\ntitle: \"Running Keep with LiteLLM\"\n---\n\n<Info>\n  This guide is for users who want to run Keep with locally hosted LL"
  },
  {
    "path": "docs/deployment/monitoring.mdx",
    "chars": 386,
    "preview": "---\ntitle: \"Monitoring\"\nsidebarTitle: \"Monitoring\"\n---\n\n# Healthchecks\n\nKeep's Backend healthcheck url:\n```\n{BACKEND_API"
  },
  {
    "path": "docs/deployment/provision/dashboard.mdx",
    "chars": 2434,
    "preview": "---\ntitle: \"Dashboard Provisioning\"\n---\n\nProvisioning dashboards in Keep allows you to configure and manage visual repre"
  },
  {
    "path": "docs/deployment/provision/overview.mdx",
    "chars": 2320,
    "preview": "---\ntitle: \"Overview\"\n---\n\nKeep supports various deployment and provisioning strategies to accommodate different environ"
  },
  {
    "path": "docs/deployment/provision/provider.mdx",
    "chars": 5576,
    "preview": "---\ntitle: \"Providers Provisioning\"\n---\n\n<Tip>For any questions or issues related to provider provisioning, please join "
  },
  {
    "path": "docs/deployment/provision/workflow.mdx",
    "chars": 1723,
    "preview": "---\ntitle: \"Workflow Provisioning\"\n---\n\n<Tip>For any questions or issues related to workflow provisioning, please join o"
  },
  {
    "path": "docs/deployment/secret-store.mdx",
    "chars": 8838,
    "preview": "---\ntitle: \"Secret Store\"\nsidebarTitle: \"Secret Store\"\n---\n\n## Overview\n\n<Tip>\n  Secret Manager selection is crucial for"
  },
  {
    "path": "docs/deployment/stress-testing.mdx",
    "chars": 9358,
    "preview": "---\ntitle: \"\"\nsidebarTitle: \"Specifications\"\n---\n\n# Specifications and Stress Testing of Keep\n<Tip>If you are using Keep"
  },
  {
    "path": "docs/development/external-url.mdx",
    "chars": 1413,
    "preview": "---\ntitle: \"Keep with an external URL\"\nsidebarTitle: \"Keep with an external URL\"\n---\n\n## Introduction\nSeveral features i"
  },
  {
    "path": "docs/development/getting-started.mdx",
    "chars": 12630,
    "preview": "---\ntitle: \"Getting started\"\nsidebarTitle: \"Getting started\"\n---\n\n### Docker-compose dev images\nYou can use `docker-comp"
  },
  {
    "path": "docs/images/datadog_raw_alerts.txt",
    "chars": 75925,
    "preview": "{\"body\": \"%%%\\ntrace_id:  \\ntags:  \\nattributes: \\n\\n@webhook-keep-datadog-webhook-integration-keep \\n@webhook-keep-data"
  },
  {
    "path": "docs/incidents/facets.mdx",
    "chars": 1951,
    "preview": "Faceted search is a powerful mechanism for enhancing search functionality, allowing users to filter and refine search re"
  },
  {
    "path": "docs/incidents/overview.mdx",
    "chars": 4065,
    "preview": "---\ntitle: \"Overview\"\n---\n\nKeep's incident management system provides a comprehensive solution for handling, tracking, a"
  },
  {
    "path": "docs/mint.json",
    "chars": 14852,
    "preview": "{\n  \"$schema\": \"https://mintlify.com/schema.json\",\n  \"name\": \"Keep\",\n  \"logo\": {\n    \"light\": \"/logo/light.png\",\n    \"da"
  },
  {
    "path": "docs/openapi.json",
    "chars": 138935,
    "preview": "{\"openapi\": \"3.0.2\", \"info\": {\"title\": \"Keep API\", \"description\": \"Rest API powering https://platform.keephq.dev and fri"
  },
  {
    "path": "docs/overview/ai-correlation.mdx",
    "chars": 1352,
    "preview": "---\ntitle: \"AI Correlation\"\n---\n\n<Tip>\nKeep Cloud: ✅ <br/>\nKeep Enterprise On-Premises: ✅ <br/>\nKeep Open Source: ⛔️\n</T"
  },
  {
    "path": "docs/overview/ai-in-workflows.mdx",
    "chars": 1229,
    "preview": "---\ntitle: \"AI in Workflows\"\n---\n\n<Tip>\nKeep Cloud: ✅ <br/>\nKeep Enterprise On-Premises: ✅ <br/>\nKeep Open Source: ✅\n</T"
  },
  {
    "path": "docs/overview/ai-incident-assistant.mdx",
    "chars": 869,
    "preview": "---\ntitle: \"AI Incident Assistant\"\n---\n\n<Tip>\nKeep Cloud: ✅ <br/>\nKeep Enterprise On-Premises: ✅ <br/>\nKeep Open Source:"
  },
  {
    "path": "docs/overview/ai-semi-automatic-correlation.mdx",
    "chars": 947,
    "preview": "---\ntitle: \"AI Semi Automatic Correlation\"\n---\n\n<Tip>\nKeep Cloud: ✅ <br/>\nKeep Enterprise On-Premises: ✅ <br/>\nKeep Open"
  },
  {
    "path": "docs/overview/ai-workflow-assistant.mdx",
    "chars": 1320,
    "preview": "---\ntitle: \"AI Workflow Builder Assistant\"\n---\n\n<Tip>\nKeep Cloud: ✅ <br/>\nKeep Enterprise On-Premises: ✅ <br/>\nKeep Open"
  },
  {
    "path": "docs/overview/alertseverityandstatus.mdx",
    "chars": 4737,
    "preview": "---\ntitle: \"Alerts Severity and Status\"\n---\n\nIn Keep, alerts are treated as first-class citizens, with clearly defined s"
  },
  {
    "path": "docs/overview/cel.mdx",
    "chars": 1352,
    "preview": "---\ntitle: \"Common Expression Language (CEL)\"\n---\n\n<Tip>\nIt worth reading [CEL official docs](https://cel.dev) to learn "
  },
  {
    "path": "docs/overview/comparisons.mdx",
    "chars": 3690,
    "preview": "---\ntitle: \"Comparison\"\n---\n\nIt's often easier to grasp a tool's features by comparing it to others in the same ecosyste"
  },
  {
    "path": "docs/overview/correlation-rules.mdx",
    "chars": 3659,
    "preview": "---\ntitle: \"Manual Correlation Rules\"\n---\n\nThe Keep Correlation Engine is a versatile tool for correlating and consolida"
  },
  {
    "path": "docs/overview/correlation-topology.mdx",
    "chars": 3660,
    "preview": "---\ntitle: \"Topology Correlation\"\n---\n\nThe Topology Processor is a core component of Keep that helps correlate alerts ba"
  },
  {
    "path": "docs/overview/deduplication.mdx",
    "chars": 4537,
    "preview": "---\ntitle: \"Deduplication\"\n---\n\nAlert deduplication is a crucial feature in Keep that helps reduce noise and streamline "
  },
  {
    "path": "docs/overview/enrichment/extraction.mdx",
    "chars": 4010,
    "preview": "---\ntitle: \"Extraction\"\n---\n\nKeep's Alert Extraction enrichment feature enables dynamic extraction of data from incoming"
  },
  {
    "path": "docs/overview/enrichment/mapping.mdx",
    "chars": 5027,
    "preview": "---\ntitle: \"Mapping\"\n---\n\nKeep's Alert Mapping enrichment feature provides a powerful mechanism for dynamically enhancin"
  },
  {
    "path": "docs/overview/faq.mdx",
    "chars": 962,
    "preview": "---\ntitle: \"FAQ\"\nsidebarTitle: FAQ\n---\n\n## FAQ\n\n### 1. \"Failed to copy alert/fingerprint. Please check your browser perm"
  },
  {
    "path": "docs/overview/fingerprints.mdx",
    "chars": 3558,
    "preview": "---\ntitle: \"Fingerprints\"\nsidebarTitle: \"Fingerprints\"\ndescription: \"Fingerprints are unique identifiers associated with"
  },
  {
    "path": "docs/overview/glossary.mdx",
    "chars": 2641,
    "preview": "---\ntitle: \"Glossary\"\n---\n## Alert\nAn alert is an event that is triggered when something bad happens or going to happen."
  },
  {
    "path": "docs/overview/howdoeskeepgetmyalerts.mdx",
    "chars": 1339,
    "preview": "---\ntitle: \"Push vs Pull alerts\"\n---\n\nThere are primarily two ways to get alerts into Keep:\n\n\n<Tip>\n  We strongly recomm"
  },
  {
    "path": "docs/overview/introduction.mdx",
    "chars": 3449,
    "preview": "---\ntitle: \"Introduction\"\ndescription: \"Keep is an open-source alert management and AIOps platform that is a swiss-knife"
  },
  {
    "path": "docs/overview/maintenance-windows.mdx",
    "chars": 6744,
    "preview": "---\ntitle: \"Maintenance Windows\"\n---\n\nKeep's Maintenance Windows feature provides a critical mechanism for managing aler"
  },
  {
    "path": "docs/overview/playground.mdx",
    "chars": 1904,
    "preview": "---\ntitle: \"Playground\"\ndescription: \"Dive into Keep's [sandbox environment](https://playground.keephq.dev) to experienc"
  },
  {
    "path": "docs/overview/servicetopology.mdx",
    "chars": 8809,
    "preview": "---\ntitle: \"Service Topology\"\n---\n\nThe Service Topology feature in Keep provides a visual representation of your service"
  },
  {
    "path": "docs/overview/support.mdx",
    "chars": 447,
    "preview": "---\ntitle: \"Support\"\nsidebarTitle: Support\n---\n\n## Overview\nYou can use the following methods to ask for support/help wi"
  },
  {
    "path": "docs/overview/usecases.mdx",
    "chars": 4198,
    "preview": "---\ntitle: \"Use Cases\"\n---\n\nKeep is a versatile platform that adapts to the needs of various roles and scenarios in IT o"
  },
  {
    "path": "docs/overview/workflow-automation.mdx",
    "chars": 2013,
    "preview": "---\ntitle: \"Workflows\"\n---\n\nWorkflow automation designed to transform how you manage alerts and incidents.\n\nIt allows yo"
  },
  {
    "path": "docs/providers/adding-a-new-provider.mdx",
    "chars": 54890,
    "preview": "---\ntitle: \"Adding a new Provider\"\nsidebarTitle: \"Adding a New Provider\"\n---\n\nThis guide explains how to create a new pr"
  },
  {
    "path": "docs/providers/documentation/airflow-provider.mdx",
    "chars": 5741,
    "preview": "---\ntitle: \"Airflow\"\nsidebarTitle: \"Airflow Provider\"\ndescription: \"The Airflow provider integration allows you to send "
  },
  {
    "path": "docs/providers/documentation/aks-provider.mdx",
    "chars": 1286,
    "preview": "---\ntitle: \"Azure AKS\"\ndescription: \"Azure AKS provider to view kubernetes resources.\"\n---\nimport AutoGeneratedSnippet f"
  },
  {
    "path": "docs/providers/documentation/amazonsqs-provider.mdx",
    "chars": 2755,
    "preview": "---\ntitle: \"AmazonSQS Provider\"\nsidebarTitle: \"AmazonSQS Provider\"\ndescription: \"The AmazonSQS provider enables you to p"
  },
  {
    "path": "docs/providers/documentation/anthropic-provider.mdx",
    "chars": 868,
    "preview": "---\ntitle: \"Anthropic Provider\"\ndescription: \"The Anthropic Provider allows for integrating Anthropic's Claude language "
  },
  {
    "path": "docs/providers/documentation/appdynamics-provider.mdx",
    "chars": 4207,
    "preview": "---\ntitle: \"AppDynamics\"\nsidebarTitle: \"AppDynamics Provider\"\ndescription: \"AppDynamics provider allows you to get AppDy"
  },
  {
    "path": "docs/providers/documentation/argocd-provider.mdx",
    "chars": 1288,
    "preview": "---\ntitle: \"ArgoCD Provider\"\nsidebarTitle: \"ArgoCD Provider\"\ndescription: \"The ArgoCD provider enables you to pull topol"
  },
  {
    "path": "docs/providers/documentation/asana-provider.mdx",
    "chars": 882,
    "preview": "---\ntitle: \"Asana\"\nsidebarTitle: \"Asana Provider\"\ndescription: \"Asana Provider allows you to create and update tasks in "
  },
  {
    "path": "docs/providers/documentation/auth0-provider.mdx",
    "chars": 943,
    "preview": "---\ntitle: \"Auth0\"\nsidebarTitle: \"Auth0 Provider\"\ndescription: \"Auth0 provider allows interaction with Auth0 APIs for au"
  },
  {
    "path": "docs/providers/documentation/axiom-provider.mdx",
    "chars": 3498,
    "preview": "---\ntitle: \"Axiom Provider\"\ndescription: \"Axiom Provider is a class that allows to ingest/digest data from Axiom.\"\n---\ni"
  },
  {
    "path": "docs/providers/documentation/azuremonitoring-provider.mdx",
    "chars": 2342,
    "preview": "---\ntitle: \"Azure Monitor\"\nsidebarTitle: \"Azure Monitor Provider\"\ndescription: \"Azure Monitorg provider allows you to ge"
  },
  {
    "path": "docs/providers/documentation/bash-provider.mdx",
    "chars": 722,
    "preview": "---\ntitle: \"Bash\"\nsidebarTitle: \"Bash Provider\"\ndescription: \"Bash provider allows executing Bash commands in a workflow"
  },
  {
    "path": "docs/providers/documentation/bigquery-provider.mdx",
    "chars": 618,
    "preview": "---\ntitle: \"BigQuery\"\nsidebarTitle: \"BigQuery Provider\"\ndescription: \"BigQuery provider allows interaction with Google B"
  },
  {
    "path": "docs/providers/documentation/centreon-provider.mdx",
    "chars": 764,
    "preview": "---\ntitle: \"Centreon\"\nsidebarTitle: \"Centreon Provider\"\ndescription: \"Centreon allows you to monitor your infrastructure"
  },
  {
    "path": "docs/providers/documentation/checkly-provider.mdx",
    "chars": 3728,
    "preview": "---\ntitle: 'Checkly'\nsidebarTitle: 'Checkly Provider'\ndescription: 'Checkly allows you to receive alerts from Checkly us"
  },
  {
    "path": "docs/providers/documentation/checkmk-provider.mdx",
    "chars": 2825,
    "preview": "---\ntitle: 'Checkmk'\nsidebarTitle: 'Checkmk Provider'\ndescription: 'Checkmk provider allows you to get alerts from Check"
  },
  {
    "path": "docs/providers/documentation/cilium-provider.mdx",
    "chars": 6224,
    "preview": "---\ntitle: \"Cilium\"\nsidebarTitle: \"Cilium Provider\"\ndescription: \"Cilium provider enables topology discovery by analyzin"
  },
  {
    "path": "docs/providers/documentation/clickhouse-provider.mdx",
    "chars": 786,
    "preview": "---\ntitle: 'ClickHouse'\nsidebarTitle: 'ClickHouse Provider'\ndescription: 'ClickHouse provider allows you to interact wit"
  },
  {
    "path": "docs/providers/documentation/cloudwatch-provider.mdx",
    "chars": 3306,
    "preview": "---\ntitle: \"CloudWatch\"\nsidebarTitle: \"CloudWatch Provider\"\ndescription: \"CloudWatch provider enables seamless integrati"
  },
  {
    "path": "docs/providers/documentation/console-provider.mdx",
    "chars": 1170,
    "preview": "---\ntitle: \"Console\"\nsidebarTitle: \"Console Provider\"\ndescription: \"Console provider is sort of a mock provider that pro"
  },
  {
    "path": "docs/providers/documentation/coralogix-provider.mdx",
    "chars": 2079,
    "preview": "---\ntitle: 'Coralogix'\nsidebarTitle: 'Coralogix Provider'\ndescription: 'Coralogix provider allows you to send alerts fro"
  },
  {
    "path": "docs/providers/documentation/dash0-provider.mdx",
    "chars": 2641,
    "preview": "---\ntitle: 'Dash0'\nsidebarTitle: 'Dash0 Provider'\ndescription: 'Dash0 provider allows you to get events from Dash0 using"
  },
  {
    "path": "docs/providers/documentation/databend-provider.mdx",
    "chars": 568,
    "preview": "---\ntitle: 'Databend'\nsidebarTitle: 'Databend Provider'\ndescription: 'Databend provider allows you to query databases'\n-"
  },
  {
    "path": "docs/providers/documentation/datadog-provider.mdx",
    "chars": 1430,
    "preview": "---\ntitle: \"Datadog\"\nsidebarTitle: \"Datadog Provider\"\ndescription: \"Datadog provider allows you to query Datadog metrics"
  },
  {
    "path": "docs/providers/documentation/deepseek-provider.mdx",
    "chars": 696,
    "preview": "---\ntitle: \"DeepSeek Provider\"\ndescription: \"The DeepSeek Provider enables integration of DeepSeek's language models int"
  },
  {
    "path": "docs/providers/documentation/discord-provider.mdx",
    "chars": 684,
    "preview": "---\ntitle: \"Discord\"\nsidebarTitle: \"Discord Provider\"\ndescription: \"Discord provider is a provider that allows to send n"
  },
  {
    "path": "docs/providers/documentation/dynatrace-provider.mdx",
    "chars": 717,
    "preview": "---\ntitle: \"Dynatrace\"\nsidebarTitle: \"Dynatrace Provider\"\ndescription: \"Dynatrace provider allows integration with Dynat"
  },
  {
    "path": "docs/providers/documentation/eks-provider.mdx",
    "chars": 2181,
    "preview": "---\ntitle: \"EKS Provider\"\ndescription: \"EKS provider integrates with AWS EKS and let you interatct with kubernetes clust"
  },
  {
    "path": "docs/providers/documentation/elastic-provider.mdx",
    "chars": 708,
    "preview": "---\ntitle: \"Elastic\"\nsidebarTitle: \"Elastic Provider\"\ndescription: \"Elastic provider is a provider used to query Elastic"
  },
  {
    "path": "docs/providers/documentation/flashduty-provider.mdx",
    "chars": 869,
    "preview": "---\ntitle: \"Flashduty\"\nsidebarTitle: \"Flashduty Provider\"\ndescription: \"Flashduty docs\"\n---\nimport AutoGeneratedSnippet "
  },
  {
    "path": "docs/providers/documentation/fluxcd-provider.mdx",
    "chars": 3803,
    "preview": "---\ntitle: \"Flux CD\"\nsidebarTitle: \"Flux CD Provider\"\ndescription: \"Flux CD Provider enables integration with Flux CD fo"
  },
  {
    "path": "docs/providers/documentation/gcpmonitoring-provider.mdx",
    "chars": 4224,
    "preview": "---\ntitle: \"GCP Monitoring\"\nsidebarTitle: \"GCP Monitoring Provider\"\ndescription: \"GCP Monitoring provider allows you to "
  },
  {
    "path": "docs/providers/documentation/gemini-provider.mdx",
    "chars": 704,
    "preview": "---\ntitle: \"Gemini Provider\"\ndescription: \"The Gemini Provider allows for integrating Google's Gemini language models in"
  },
  {
    "path": "docs/providers/documentation/github-provider.mdx",
    "chars": 705,
    "preview": "---\ntitle: \"GitHub\"\nsidebarTitle: \"GitHub Provider\"\ndescription: \"GitHub provider allows integration with GitHub for man"
  },
  {
    "path": "docs/providers/documentation/github_workflows_provider.mdx",
    "chars": 1439,
    "preview": "---\ntitle: \"Github Workflows\"\nsidebarTitle: \"Github Workflows Provider\"\ndescription: \"GithubWorkflowProvider is a provid"
  },
  {
    "path": "docs/providers/documentation/gitlab-provider.mdx",
    "chars": 923,
    "preview": "---\ntitle: \"GitLab Provider\"\nsidebarTitle: \"GitLab Provider\"\ndescription: \"GitLab provider is a provider used for creati"
  },
  {
    "path": "docs/providers/documentation/gitlabpipelines-provider.mdx",
    "chars": 854,
    "preview": "---\ntitle: \"GitLab Pipelines\"\nsidebarTitle: \"GitLab Pipelines Provider\"\ndescription: \"GitLab Pipelines Provider is a pro"
  },
  {
    "path": "docs/providers/documentation/gke-provider.mdx",
    "chars": 847,
    "preview": "---\ntitle: \"Google Kubernetes Engine\"\nsidebarTitle: \"Google Kubernetes Engine Provider\"\ndescription: \"Google Kubernetes "
  },
  {
    "path": "docs/providers/documentation/google_chat-provider.mdx",
    "chars": 811,
    "preview": "---\ntitle: \"Google Chat\"\nsidebarTitle: \"Google Chat Provider\"\ndescription: \"Google Chat provider is a provider that allo"
  },
  {
    "path": "docs/providers/documentation/grafana-provider.mdx",
    "chars": 4448,
    "preview": "---\ntitle: \"Grafana Provider\"\ndescription: \"Grafana Provider allows either pull/push alerts and pull Topology Map from G"
  },
  {
    "path": "docs/providers/documentation/grafana_incident-provider.mdx",
    "chars": 3404,
    "preview": "---\ntitle: 'Grafana Incident Provider'\nsidebarTitle: 'Grafana Incident Provider'\ndescription: 'Grafana Incident Provider"
  },
  {
    "path": "docs/providers/documentation/grafana_loki-provider.mdx",
    "chars": 3517,
    "preview": "---\ntitle: 'Grafana Loki'\nsidebarTitle: 'Grafana Loki Provider'\ndescription: 'Grafana Loki provider allows you to query "
  },
  {
    "path": "docs/providers/documentation/grafana_oncall-provider.mdx",
    "chars": 1381,
    "preview": "---\ntitle: \"Grafana OnCall Provider\"\ndescription: \"Grafana Oncall Provider is a class that allows to ingest data to the "
  },
  {
    "path": "docs/providers/documentation/graylog-provider.mdx",
    "chars": 2000,
    "preview": "---\ntitle: \"Graylog Provider\"\nsidebarTitle: \"Graylog Provider\"\ndescription: \"The Graylog provider enables webhook instal"
  },
  {
    "path": "docs/providers/documentation/grok-provider.mdx",
    "chars": 560,
    "preview": "---\ntitle: \"Grok Provider\"\ndescription: \"The Grok Provider allows for integrating X.AI's Grok language models into Keep."
  },
  {
    "path": "docs/providers/documentation/http-provider.mdx",
    "chars": 850,
    "preview": "---\ntitle: \"HTTP Provider\"\ndescription: \"HTTP Provider is a provider used to query/notify using HTTP requests\"\n---\nimpor"
  },
  {
    "path": "docs/providers/documentation/icinga2-provider.mdx",
    "chars": 3778,
    "preview": "---\ntitle: \"Icinga2 Provider\"\nsidebarTitle: \"Icinga2\"\ndescription: \"Icinga2 Provider Allows Reception of Push Alerts fro"
  },
  {
    "path": "docs/providers/documentation/ilert-provider.mdx",
    "chars": 1655,
    "preview": "---\ntitle: \"ilert Provider\"\nsidebarTitle: \"ilert Provider\"\ndescription: \"The ilert provider facilitates interaction with"
  },
  {
    "path": "docs/providers/documentation/incidentio-provider.mdx",
    "chars": 1605,
    "preview": "---\ntitle: \"Incident.io Provider\"\nsidebarTitle: \"Incident.io Provider\"\ndescription: \"The Incident.io provider enables th"
  },
  {
    "path": "docs/providers/documentation/incidentmanager-provider.mdx",
    "chars": 841,
    "preview": "---\ntitle: \"Incident Manager Provider\"\nsidebarTitle: \"Incident Manager Provider\"\n---\nimport AutoGeneratedSnippet from '/"
  },
  {
    "path": "docs/providers/documentation/jira-on-prem-provider.mdx",
    "chars": 401,
    "preview": "---\ntitle: \"Jira On-Prem Provider\"\nsidebarTitle: \"Jira On-Prem Provider\"\ndescription: \"Jira On-Prem Provider is a provid"
  },
  {
    "path": "docs/providers/documentation/jira-provider.mdx",
    "chars": 7630,
    "preview": "---\ntitle: \"Jira Cloud Provider\"\nsidebarTitle: \"Jira Cloud Provider\"\ndescription: \"Jira Cloud provider is a provider use"
  },
  {
    "path": "docs/providers/documentation/kafka-provider.mdx",
    "chars": 723,
    "preview": "---\ntitle: \"Kafka\"\nsidebarTitle: \"Kafka Provider\"\ndescription: \"Kafka provider allows integration with Apache Kafka for "
  },
  {
    "path": "docs/providers/documentation/keep-provider.mdx",
    "chars": 655,
    "preview": "---\ntitle: \"Keep\"\nsidebarTitle: \"Keep Provider\"\ndescription: \"Keep provider allows you to query and manage alerts in Kee"
  },
  {
    "path": "docs/providers/documentation/kibana-provider.mdx",
    "chars": 1871,
    "preview": "---\ntitle: \"Kibana\"\nsidebarTitle: \"Kibana Provider\"\ndescription: \"Kibana provider allows you get alerts from Kibana Aler"
  },
  {
    "path": "docs/providers/documentation/kubernetes-provider.mdx",
    "chars": 728,
    "preview": "---\ntitle: \"Kubernetes\"\ndescription: \"Kubernetes provider to perform rollout restart or list pods action.\"\n---\nimport Au"
  },
  {
    "path": "docs/providers/documentation/libre_nms-provider.mdx",
    "chars": 4029,
    "preview": "---\ntitle: 'LibreNMS'\nsidebarTitle: 'LibreNMS Provider'\ndescription: 'LibreNMS allows you to receive alerts from LibreNM"
  },
  {
    "path": "docs/providers/documentation/linear_provider.mdx",
    "chars": 1055,
    "preview": "---\ntitle: \"Linear Provider\"\nsidebarTitle: \"Linear Provider\"\ndescription: \"Linear Provider is a provider for fetching da"
  }
]

// ... and 2012 more files (download for full content)

About this extraction

This page contains the full source code of the keephq/keep GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 2212 files (8.9 MB), approximately 2.5M tokens, and a symbol index with 5841 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!