diff --git a/.github/workflows/pre-release.yml b/.github/workflows/pre-release.yml
index 70d85277..53712580 100644
--- a/.github/workflows/pre-release.yml
+++ b/.github/workflows/pre-release.yml
@@ -91,6 +91,19 @@ jobs:
- name: Build frontend
run: npm run frontend:build
+ env:
+ SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
+
+ - name: Create Sentry release
+ uses: getsentry/action-release@v3
+ env:
+ SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
+ SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
+ SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
+ with:
+ release: ${{ needs.bump-version.outputs.new_version }}
+ environment: production
+ sourcemaps: "./frontend/dist"
- name: Upload frontend artifact
uses: actions/upload-artifact@v4
@@ -170,6 +183,17 @@ jobs:
env:
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: ${{ matrix.target == 'aarch64-unknown-linux-gnu' && 'aarch64-linux-gnu-gcc' || '' }}
+ - name: Setup Sentry CLI
+ uses: matbour/setup-sentry-cli@v2
+ with:
+ token: ${{ secrets.SENTRY_AUTH_TOKEN }}
+ organization: ${{ secrets.SENTRY_ORG }}
+ project: ${{ secrets.SENTRY_PROJECT }}
+ version: 2.21.2
+
+ - name: Upload source maps to Sentry
+ run: sentry-cli debug-files upload --include-sources target/${{ matrix.target }}/release
+
- name: Prepare binaries (non-macOS)
if: runner.os != 'macOS'
shell: bash
diff --git a/.gitignore b/.gitignore
index 4c871084..32be2889 100644
--- a/.gitignore
+++ b/.gitignore
@@ -79,4 +79,5 @@ backend/db.sqlite
# Development ports file
.dev-ports.json
-dev_assets
\ No newline at end of file
+dev_assets
+/frontend/.env.sentry-build-plugin
diff --git a/backend/Cargo.toml b/backend/Cargo.toml
index 0804ca4e..e7174f6b 100644
--- a/backend/Cargo.toml
+++ b/backend/Cargo.toml
@@ -42,6 +42,14 @@ schemars = "0.8"
regex = "1.11.1"
notify-rust = "4.11"
octocrab = "0.44"
+sentry = { version = "0.41.0", features = ["anyhow", "backtrace", "panic", "debug-images"] }
+sentry-tower = "0.41.0"
+sentry-tracing = { version = "0.41.0", features = ["backtrace"] }
[build-dependencies]
ts-rs = { version = "9.0", features = ["uuid-impl", "chrono-impl"] }
+
+[profile.release]
+debug = true
+split-debuginfo = "packed"
+strip = true
\ No newline at end of file
diff --git a/backend/src/bin/mcp_task_server.rs b/backend/src/bin/mcp_task_server.rs
index 116dfd48..d5065459 100644
--- a/backend/src/bin/mcp_task_server.rs
+++ b/backend/src/bin/mcp_task_server.rs
@@ -2,33 +2,57 @@ use std::str::FromStr;
use rmcp::{transport::stdio, ServiceExt};
use sqlx::{sqlite::SqliteConnectOptions, SqlitePool};
-use vibe_kanban::{mcp::task_server::TaskServer, utils::asset_dir};
+use tracing_subscriber::{prelude::*, EnvFilter};
+use vibe_kanban::{mcp::task_server::TaskServer, sentry_layer, utils::asset_dir};
-#[tokio::main]
-async fn main() -> anyhow::Result<()> {
- tracing_subscriber::fmt()
- .with_env_filter("debug")
- .with_writer(std::io::stderr)
- .init();
+fn main() -> anyhow::Result<()> {
+ let environment = if cfg!(debug_assertions) {
+ "dev"
+ } else {
+ "production"
+ };
+ let _guard = sentry::init(("https://1065a1d276a581316999a07d5dffee26@o4509603705192449.ingest.de.sentry.io/4509605576441937", sentry::ClientOptions {
+ release: sentry::release_name!(),
+ environment: Some(environment.into()),
+ ..Default::default()
+ }));
+ sentry::configure_scope(|scope| {
+ scope.set_tag("source", "mcp");
+ });
+ tokio::runtime::Builder::new_multi_thread()
+ .enable_all()
+ .build()
+ .unwrap()
+ .block_on(async {
+ tracing_subscriber::registry()
+ .with(
+ tracing_subscriber::fmt::layer()
+ .with_writer(std::io::stderr)
+ .with_filter(EnvFilter::new("debug")),
+ )
+ .with(sentry_layer())
+ .init();
- tracing::debug!("[MCP] Starting MCP task server...");
+ tracing::debug!("[MCP] Starting MCP task server...");
- // Database connection
- let database_url = format!(
- "sqlite://{}",
- asset_dir().join("db.sqlite").to_string_lossy()
- );
+ // Database connection
+ let database_url = format!(
+ "sqlite://{}",
+ asset_dir().join("db.sqlite").to_string_lossy()
+ );
- let options = SqliteConnectOptions::from_str(&database_url)?.create_if_missing(false);
- let pool = SqlitePool::connect_with(options).await?;
+ let options = SqliteConnectOptions::from_str(&database_url)?.create_if_missing(false);
+ let pool = SqlitePool::connect_with(options).await?;
- let service = TaskServer::new(pool)
- .serve(stdio())
- .await
- .inspect_err(|e| {
- tracing::error!("serving error: {:?}", e);
- })?;
+ let service = TaskServer::new(pool)
+ .serve(stdio())
+ .await
+ .inspect_err(|e| {
+ tracing::error!("serving error: {:?}", e);
+ sentry::capture_error(e);
+ })?;
- service.waiting().await?;
- Ok(())
+ service.waiting().await?;
+ Ok(())
+ })
}
diff --git a/backend/src/lib.rs b/backend/src/lib.rs
index fb74c107..404b37d0 100644
--- a/backend/src/lib.rs
+++ b/backend/src/lib.rs
@@ -1,4 +1,6 @@
use rust_embed::RustEmbed;
+use sentry_tracing::{EventFilter, SentryLayer};
+use tracing::Level;
pub mod app_state;
pub mod execution_monitor;
@@ -24,3 +26,22 @@ pub struct SoundAssets;
#[derive(RustEmbed)]
#[folder = "scripts"]
pub struct ScriptAssets;
+
+pub fn sentry_layer() -> SentryLayer
+where
+ S: tracing::Subscriber,
+ S: for<'a> tracing_subscriber::registry::LookupSpan<'a>,
+{
+ SentryLayer::default()
+ .span_filter(|meta| {
+ matches!(
+ *meta.level(),
+ Level::DEBUG | Level::INFO | Level::WARN | Level::ERROR
+ )
+ })
+ .event_filter(|meta| match *meta.level() {
+ Level::ERROR => EventFilter::Event,
+ Level::DEBUG | Level::INFO | Level::WARN => EventFilter::Breadcrumb,
+ Level::TRACE => EventFilter::Ignore,
+ })
+}
diff --git a/backend/src/main.rs b/backend/src/main.rs
index 85273bde..31b65032 100644
--- a/backend/src/main.rs
+++ b/backend/src/main.rs
@@ -8,10 +8,12 @@ use axum::{
routing::{get, post},
Json, Router,
};
+use sentry_tower::NewSentryLayer;
use sqlx::{sqlite::SqliteConnectOptions, SqlitePool};
use tokio::sync::RwLock;
use tower_http::cors::CorsLayer;
-use vibe_kanban::{Assets, ScriptAssets, SoundAssets};
+use tracing_subscriber::{filter::LevelFilter, prelude::*};
+use vibe_kanban::{sentry_layer, Assets, ScriptAssets, SoundAssets};
mod app_state;
mod execution_monitor;
@@ -116,96 +118,119 @@ async fn serve_sound_file(
}
}
-#[tokio::main]
-async fn main() -> anyhow::Result<()> {
- tracing_subscriber::fmt().init();
-
- // Create asset directory if it doesn't exist
- if !utils::asset_dir().exists() {
- std::fs::create_dir_all(utils::asset_dir())?;
- }
-
- // Database connection
- let database_url = format!(
- "sqlite://{}",
- utils::asset_dir().join("db.sqlite").to_string_lossy()
- );
-
- let options = SqliteConnectOptions::from_str(&database_url)?.create_if_missing(true);
- let pool = SqlitePool::connect_with(options).await?;
- sqlx::migrate!("./migrations").run(&pool).await?;
-
- // Load configuration
- let config_path = utils::config_path();
- let config = Config::load(&config_path)?;
- let config_arc = Arc::new(RwLock::new(config));
-
- // Create app state
- let app_state = AppState::new(pool.clone(), config_arc.clone());
-
- // Start background task to check for init status and spawn processes
- let state_clone = app_state.clone();
- tokio::spawn(async move {
- execution_monitor(state_clone).await;
+fn main() -> anyhow::Result<()> {
+ let environment = if cfg!(debug_assertions) {
+ "dev"
+ } else {
+ "production"
+ };
+ let _guard = sentry::init(("https://1065a1d276a581316999a07d5dffee26@o4509603705192449.ingest.de.sentry.io/4509605576441937", sentry::ClientOptions {
+ release: sentry::release_name!(),
+ environment: Some(environment.into()),
+ attach_stacktrace: true,
+ ..Default::default()
+ }));
+ sentry::configure_scope(|scope| {
+ scope.set_tag("source", "server");
});
+ tokio::runtime::Builder::new_multi_thread()
+ .enable_all()
+ .build()
+ .unwrap()
+ .block_on(async {
+ tracing_subscriber::registry()
+ .with(tracing_subscriber::fmt::layer().with_filter(LevelFilter::INFO))
+ .with(sentry_layer())
+ .init();
- // Start PR monitoring service
- let pr_monitor = PrMonitorService::new(pool.clone());
- let config_for_monitor = config_arc.clone();
+ // Create asset directory if it doesn't exist
+ if !utils::asset_dir().exists() {
+ std::fs::create_dir_all(utils::asset_dir())?;
+ }
- tokio::spawn(async move {
- pr_monitor.start_with_config(config_for_monitor).await;
- });
+ // Database connection
+ let database_url = format!(
+ "sqlite://{}",
+ utils::asset_dir().join("db.sqlite").to_string_lossy()
+ );
- // Public routes (no auth required)
- let public_routes = Router::new()
- .route("/api/health", get(health::health_check))
- .route("/api/echo", post(echo_handler));
+ let options = SqliteConnectOptions::from_str(&database_url)?.create_if_missing(true);
+ let pool = SqlitePool::connect_with(options).await?;
+ sqlx::migrate!("./migrations").run(&pool).await?;
- // All routes (no auth required)
- let app_routes = Router::new()
- .nest(
- "/api",
- Router::new()
- .merge(projects::projects_router())
- .merge(tasks::tasks_router())
- .merge(task_attempts::task_attempts_router())
- .merge(filesystem::filesystem_router())
- .merge(config::config_router())
- .route("/sounds/:filename", get(serve_sound_file)),
- )
- .layer(Extension(pool.clone()))
- .layer(Extension(config_arc));
+ // Load configuration
+ let config_path = utils::config_path();
+ let config = Config::load(&config_path)?;
+ let config_arc = Arc::new(RwLock::new(config));
- let app = Router::new()
- .merge(public_routes)
- .merge(app_routes)
- // Static file serving routes
- .route("/", get(index_handler))
- .route("/*path", get(static_handler))
- .layer(Extension(pool))
- .layer(Extension(app_state))
- .layer(CorsLayer::permissive());
+ // Create app state
+ let app_state = AppState::new(pool.clone(), config_arc.clone());
- let port: u16 = std::env::var("BACKEND_PORT")
- .or_else(|_| std::env::var("PORT"))
- .ok()
- .and_then(|p| p.parse().ok())
- .unwrap_or(0); // Use 0 to find free port if no specific port provided
+ // Start background task to check for init status and spawn processes
+ let state_clone = app_state.clone();
+ tokio::spawn(async move {
+ execution_monitor(state_clone).await;
+ });
- let listener = tokio::net::TcpListener::bind(format!("0.0.0.0:{port}")).await?;
- let actual_port = listener.local_addr()?.port(); // get โ 53427 (example)
+ // Start PR monitoring service
+ let pr_monitor = PrMonitorService::new(pool.clone());
+ let config_for_monitor = config_arc.clone();
- tracing::info!("Server running on http://0.0.0.0:{actual_port}");
+ tokio::spawn(async move {
+ pr_monitor.start_with_config(config_for_monitor).await;
+ });
- if !cfg!(debug_assertions) {
- tracing::info!("Opening browser...");
- if let Err(e) = utils::open_browser(&format!("http://127.0.0.1:{actual_port}")).await {
- tracing::warn!("Failed to open browser automatically: {}. Please open http://127.0.0.1:{} manually.", e, actual_port);
- }
- }
+ // Public routes (no auth required)
+ let public_routes = Router::new()
+ .route("/api/health", get(health::health_check))
+ .route("/api/echo", post(echo_handler));
- axum::serve(listener, app).await?;
+ // All routes (no auth required)
+ let app_routes = Router::new()
+ .nest(
+ "/api",
+ Router::new()
+ .merge(projects::projects_router())
+ .merge(tasks::tasks_router())
+ .merge(task_attempts::task_attempts_router())
+ .merge(filesystem::filesystem_router())
+ .merge(config::config_router())
+ .route("/sounds/:filename", get(serve_sound_file)),
+ )
+ .layer(Extension(pool.clone()))
+ .layer(Extension(config_arc));
- Ok(())
+ let app = Router::new()
+ .merge(public_routes)
+ .merge(app_routes)
+ // Static file serving routes
+ .route("/", get(index_handler))
+ .route("/*path", get(static_handler))
+ .layer(Extension(pool))
+ .layer(Extension(app_state))
+ .layer(CorsLayer::permissive())
+ .layer(NewSentryLayer::new_from_top());
+
+ let port: u16 = std::env::var("BACKEND_PORT")
+ .or_else(|_| std::env::var("PORT"))
+ .ok()
+ .and_then(|p| p.parse().ok())
+ .unwrap_or(0); // Use 0 to find free port if no specific port provided
+
+ let listener = tokio::net::TcpListener::bind(format!("0.0.0.0:{port}")).await?;
+ let actual_port = listener.local_addr()?.port(); // get โ 53427 (example)
+
+ tracing::info!("Server running on http://0.0.0.0:{actual_port}");
+
+ if !cfg!(debug_assertions) {
+ tracing::info!("Opening browser...");
+ if let Err(e) = utils::open_browser(&format!("http://127.0.0.1:{actual_port}")).await {
+ tracing::warn!("Failed to open browser automatically: {}. Please open http://127.0.0.1:{} manually.", e, actual_port);
+ }
+ }
+
+ axum::serve(listener, app).await?;
+
+ Ok(())
+ })
}
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index cf157936..60055611 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -17,6 +17,8 @@
"@radix-ui/react-separator": "^1.1.7",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-tooltip": "^1.2.7",
+ "@sentry/react": "^9.34.0",
+ "@sentry/vite-plugin": "^3.5.0",
"class-variance-authority": "^0.7.0",
"click-to-react-component": "^1.1.2",
"clsx": "^2.0.0",
@@ -62,7 +64,6 @@
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
"integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
- "dev": true,
"license": "Apache-2.0",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
@@ -76,7 +77,6 @@
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
"integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-validator-identifier": "^7.27.1",
@@ -91,7 +91,6 @@
"version": "7.27.5",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.5.tgz",
"integrity": "sha512-KiRAp/VoJaWkkte84TvUd9qjdbZAdiqyvMxrGl1N6vzFogKmaLgoM3L1kgtLicp2HP5fBJS8JrZKLVIZGVJAVg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -101,7 +100,6 @@
"version": "7.27.4",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.4.tgz",
"integrity": "sha512-bXYxrXFubeYdvB0NhD/NBB3Qi6aZeV20GOWVI47t2dkecCEoneR4NPVcb7abpXDEvejgrUfFtG6vG/zxAKmg+g==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@ampproject/remapping": "^2.2.0",
@@ -132,7 +130,6 @@
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
- "dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -142,7 +139,6 @@
"version": "7.27.5",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.5.tgz",
"integrity": "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.27.5",
@@ -159,7 +155,6 @@
"version": "7.27.2",
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz",
"integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/compat-data": "^7.27.2",
@@ -176,7 +171,6 @@
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
- "dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -186,7 +180,6 @@
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz",
"integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/traverse": "^7.27.1",
@@ -200,7 +193,6 @@
"version": "7.27.3",
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz",
"integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-module-imports": "^7.27.1",
@@ -228,7 +220,6 @@
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -238,7 +229,6 @@
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
"integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -248,7 +238,6 @@
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz",
"integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -258,7 +247,6 @@
"version": "7.27.6",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.6.tgz",
"integrity": "sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/template": "^7.27.2",
@@ -272,7 +260,6 @@
"version": "7.27.5",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.5.tgz",
"integrity": "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.27.3"
@@ -320,7 +307,6 @@
"version": "7.27.2",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
"integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.27.1",
@@ -335,7 +321,6 @@
"version": "7.27.4",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.4.tgz",
"integrity": "sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.27.1",
@@ -354,7 +339,6 @@
"version": "7.27.6",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.6.tgz",
"integrity": "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-string-parser": "^7.27.1",
@@ -2199,6 +2183,370 @@
"win32"
]
},
+ "node_modules/@sentry-internal/browser-utils": {
+ "version": "9.34.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-9.34.0.tgz",
+ "integrity": "sha512-pXVznvP4CROejYtk6y7UQvPTieWz2vXjukGlO45fsnQa9nNo30lkQh3Ws2HZw2YbTxYZQYx75FBDezwKl2q0hQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@sentry/core": "9.34.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@sentry-internal/browser-utils/node_modules/@sentry/core": {
+ "version": "9.34.0",
+ "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.34.0.tgz",
+ "integrity": "sha512-M/zikVaE3KLkhCFDyrHB35sF7pVkB2RPy07BcRsdFsSsdpjoG+Zq2Sxth2tMTbjd0x9Vtb/X6LVjyCj9GSEvVg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@sentry-internal/feedback": {
+ "version": "9.34.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-9.34.0.tgz",
+ "integrity": "sha512-HT/EBRl1DR8XqlJk2wFNPJFcnIzNcEDjmW7C/o7K0GeP5jcSH0dKpcH7ykz2bi46gMRPrkO5EK2eXGK81KYI3g==",
+ "license": "MIT",
+ "dependencies": {
+ "@sentry/core": "9.34.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@sentry-internal/feedback/node_modules/@sentry/core": {
+ "version": "9.34.0",
+ "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.34.0.tgz",
+ "integrity": "sha512-M/zikVaE3KLkhCFDyrHB35sF7pVkB2RPy07BcRsdFsSsdpjoG+Zq2Sxth2tMTbjd0x9Vtb/X6LVjyCj9GSEvVg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@sentry-internal/replay": {
+ "version": "9.34.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-9.34.0.tgz",
+ "integrity": "sha512-joYSqWltmpkcqI8Gg8jwFtPv0F01whmuQfNGoGaL7Z6B/xO1vvkqEudrg1tmswUHhqtYpZYaEaCvrmv0sPGCfA==",
+ "license": "MIT",
+ "dependencies": {
+ "@sentry-internal/browser-utils": "9.34.0",
+ "@sentry/core": "9.34.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@sentry-internal/replay-canvas": {
+ "version": "9.34.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-9.34.0.tgz",
+ "integrity": "sha512-GCtqMFk9WwrU3JNz1tlCFAhzmNfgZhLRaS0cLzoTuxPbG3CC2VUIWYEOw7+AdCJZGm8ElTMxu+BkChgGb8qthQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@sentry-internal/replay": "9.34.0",
+ "@sentry/core": "9.34.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@sentry-internal/replay-canvas/node_modules/@sentry/core": {
+ "version": "9.34.0",
+ "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.34.0.tgz",
+ "integrity": "sha512-M/zikVaE3KLkhCFDyrHB35sF7pVkB2RPy07BcRsdFsSsdpjoG+Zq2Sxth2tMTbjd0x9Vtb/X6LVjyCj9GSEvVg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@sentry-internal/replay/node_modules/@sentry/core": {
+ "version": "9.34.0",
+ "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.34.0.tgz",
+ "integrity": "sha512-M/zikVaE3KLkhCFDyrHB35sF7pVkB2RPy07BcRsdFsSsdpjoG+Zq2Sxth2tMTbjd0x9Vtb/X6LVjyCj9GSEvVg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@sentry/babel-plugin-component-annotate": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-3.5.0.tgz",
+ "integrity": "sha512-s2go8w03CDHbF9luFGtBHKJp4cSpsQzNVqgIa9Pfa4wnjipvrK6CxVT4icpLA3YO6kg5u622Yoa5GF3cJdippw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/@sentry/browser": {
+ "version": "9.34.0",
+ "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-9.34.0.tgz",
+ "integrity": "sha512-6oJxU7JEA/RCgMTVlHXT54U9d0DWg61GgzyLTM+FUa8OUrAoK/t+CZGSMc/13nYN8xs7vcpiORdRx0ogch9zGw==",
+ "license": "MIT",
+ "dependencies": {
+ "@sentry-internal/browser-utils": "9.34.0",
+ "@sentry-internal/feedback": "9.34.0",
+ "@sentry-internal/replay": "9.34.0",
+ "@sentry-internal/replay-canvas": "9.34.0",
+ "@sentry/core": "9.34.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@sentry/browser/node_modules/@sentry/core": {
+ "version": "9.34.0",
+ "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.34.0.tgz",
+ "integrity": "sha512-M/zikVaE3KLkhCFDyrHB35sF7pVkB2RPy07BcRsdFsSsdpjoG+Zq2Sxth2tMTbjd0x9Vtb/X6LVjyCj9GSEvVg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@sentry/bundler-plugin-core": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/@sentry/bundler-plugin-core/-/bundler-plugin-core-3.5.0.tgz",
+ "integrity": "sha512-zDzPrhJqAAy2VzV4g540qAZH4qxzisstK2+NIJPZUUKztWRWUV2cMHsyUtdctYgloGkLyGpZJBE3RE6dmP/xqQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.18.5",
+ "@sentry/babel-plugin-component-annotate": "3.5.0",
+ "@sentry/cli": "2.42.2",
+ "dotenv": "^16.3.1",
+ "find-up": "^5.0.0",
+ "glob": "^9.3.2",
+ "magic-string": "0.30.8",
+ "unplugin": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/@sentry/bundler-plugin-core/node_modules/glob": {
+ "version": "9.3.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz",
+ "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==",
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "minimatch": "^8.0.2",
+ "minipass": "^4.2.4",
+ "path-scurry": "^1.6.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@sentry/bundler-plugin-core/node_modules/minimatch": {
+ "version": "8.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz",
+ "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@sentry/bundler-plugin-core/node_modules/minipass": {
+ "version": "4.2.8",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz",
+ "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@sentry/cli": {
+ "version": "2.42.2",
+ "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.42.2.tgz",
+ "integrity": "sha512-spb7S/RUumCGyiSTg8DlrCX4bivCNmU/A1hcfkwuciTFGu8l5CDc2I6jJWWZw8/0enDGxuj5XujgXvU5tr4bxg==",
+ "hasInstallScript": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "https-proxy-agent": "^5.0.0",
+ "node-fetch": "^2.6.7",
+ "progress": "^2.0.3",
+ "proxy-from-env": "^1.1.0",
+ "which": "^2.0.2"
+ },
+ "bin": {
+ "sentry-cli": "bin/sentry-cli"
+ },
+ "engines": {
+ "node": ">= 10"
+ },
+ "optionalDependencies": {
+ "@sentry/cli-darwin": "2.42.2",
+ "@sentry/cli-linux-arm": "2.42.2",
+ "@sentry/cli-linux-arm64": "2.42.2",
+ "@sentry/cli-linux-i686": "2.42.2",
+ "@sentry/cli-linux-x64": "2.42.2",
+ "@sentry/cli-win32-i686": "2.42.2",
+ "@sentry/cli-win32-x64": "2.42.2"
+ }
+ },
+ "node_modules/@sentry/cli-darwin": {
+ "version": "2.42.2",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.42.2.tgz",
+ "integrity": "sha512-GtJSuxER7Vrp1IpxdUyRZzcckzMnb4N5KTW7sbTwUiwqARRo+wxS+gczYrS8tdgtmXs5XYhzhs+t4d52ITHMIg==",
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@sentry/cli-linux-arm": {
+ "version": "2.42.2",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-2.42.2.tgz",
+ "integrity": "sha512-7udCw+YL9lwq+9eL3WLspvnuG+k5Icg92YE7zsteTzWLwgPVzaxeZD2f8hwhsu+wmL+jNqbpCRmktPteh3i2mg==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "os": [
+ "linux",
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@sentry/cli-linux-arm64": {
+ "version": "2.42.2",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.42.2.tgz",
+ "integrity": "sha512-BOxzI7sgEU5Dhq3o4SblFXdE9zScpz6EXc5Zwr1UDZvzgXZGosUtKVc7d1LmkrHP8Q2o18HcDWtF3WvJRb5Zpw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "os": [
+ "linux",
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@sentry/cli-linux-i686": {
+ "version": "2.42.2",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-2.42.2.tgz",
+ "integrity": "sha512-Sw/dQp5ZPvKnq3/y7wIJyxTUJYPGoTX/YeMbDs8BzDlu9to2LWV3K3r7hE7W1Lpbaw4tSquUHiQjP5QHCOS7aQ==",
+ "cpu": [
+ "x86",
+ "ia32"
+ ],
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "os": [
+ "linux",
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@sentry/cli-linux-x64": {
+ "version": "2.42.2",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-2.42.2.tgz",
+ "integrity": "sha512-mU4zUspAal6TIwlNLBV5oq6yYqiENnCWSxtSQVzWs0Jyq97wtqGNG9U+QrnwjJZ+ta/hvye9fvL2X25D/RxHQw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "os": [
+ "linux",
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@sentry/cli-win32-i686": {
+ "version": "2.42.2",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-2.42.2.tgz",
+ "integrity": "sha512-iHvFHPGqgJMNqXJoQpqttfsv2GI3cGodeTq4aoVLU/BT3+hXzbV0x1VpvvEhncJkDgDicJpFLM8sEPHb3b8abw==",
+ "cpu": [
+ "x86",
+ "ia32"
+ ],
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@sentry/cli-win32-x64": {
+ "version": "2.42.2",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.42.2.tgz",
+ "integrity": "sha512-vPPGHjYoaGmfrU7xhfFxG7qlTBacroz5NdT+0FmDn6692D8IvpNXl1K+eV3Kag44ipJBBeR8g1HRJyx/F/9ACw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@sentry/react": {
+ "version": "9.34.0",
+ "resolved": "https://registry.npmjs.org/@sentry/react/-/react-9.34.0.tgz",
+ "integrity": "sha512-xrai0g8qBS0AyiAytHlrBiTPu1zG7DNNh4GodAkHcd1j2iVti2c+AR7KgUY7UrsrjXd8Fpy7c+qo+5DnHLpulw==",
+ "license": "MIT",
+ "dependencies": {
+ "@sentry/browser": "9.34.0",
+ "@sentry/core": "9.34.0",
+ "hoist-non-react-statics": "^3.3.2"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "react": "^16.14.0 || 17.x || 18.x || 19.x"
+ }
+ },
+ "node_modules/@sentry/react/node_modules/@sentry/core": {
+ "version": "9.34.0",
+ "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.34.0.tgz",
+ "integrity": "sha512-M/zikVaE3KLkhCFDyrHB35sF7pVkB2RPy07BcRsdFsSsdpjoG+Zq2Sxth2tMTbjd0x9Vtb/X6LVjyCj9GSEvVg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@sentry/vite-plugin": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/@sentry/vite-plugin/-/vite-plugin-3.5.0.tgz",
+ "integrity": "sha512-jUnpTdpicG8wefamw7eNo2uO+Q3KCbOAiF76xH4gfNHSW6TN2hBfOtmLu7J+ive4c0Al3+NEHz19bIPR0lkwWg==",
+ "license": "MIT",
+ "dependencies": {
+ "@sentry/bundler-plugin-core": "3.5.0",
+ "unplugin": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
"node_modules/@types/babel__core": {
"version": "7.20.5",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
@@ -2523,7 +2871,6 @@
"version": "8.15.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
- "dev": true,
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
@@ -2542,6 +2889,18 @@
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
+ "node_modules/agent-base": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
"node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -2718,7 +3077,6 @@
"version": "4.25.0",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.0.tgz",
"integrity": "sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==",
- "dev": true,
"funding": [
{
"type": "opencollective",
@@ -2770,7 +3128,6 @@
"version": "1.0.30001723",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001723.tgz",
"integrity": "sha512-1R/elMjtehrFejxwmexeXAtae5UO9iSyFn6G/I806CYC/BLyyBk1EPhrKBkWhy6wM6Xnm47dSJQec+tLJ39WHw==",
- "dev": true,
"funding": [
{
"type": "opencollective",
@@ -2913,7 +3270,6 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
- "dev": true,
"license": "MIT"
},
"node_modules/cross-spawn": {
@@ -2953,7 +3309,6 @@
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
"integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@@ -3018,6 +3373,18 @@
"node": ">=6.0.0"
}
},
+ "node_modules/dotenv": {
+ "version": "16.6.1",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
+ "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
"node_modules/eastasianwidth": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
@@ -3028,7 +3395,6 @@
"version": "1.5.170",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.170.tgz",
"integrity": "sha512-GP+M7aeluQo9uAyiTCxgIj/j+PrWhMlY7LFVj8prlsPljd0Fdg9AprlfUi+OCSFWy9Y5/2D/Jrj9HS8Z4rpKWA==",
- "dev": true,
"license": "ISC"
},
"node_modules/emoji-regex": {
@@ -3080,7 +3446,6 @@
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -3454,7 +3819,6 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
"integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
- "dev": true,
"license": "MIT",
"dependencies": {
"locate-path": "^6.0.0",
@@ -3523,7 +3887,6 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
- "dev": true,
"license": "ISC"
},
"node_modules/fsevents": {
@@ -3553,7 +3916,6 @@
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
"integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -3630,7 +3992,6 @@
"version": "11.12.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
@@ -3686,12 +4047,34 @@
"node": ">= 0.4"
}
},
+ "node_modules/hoist-non-react-statics": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+ "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "react-is": "^16.7.0"
+ }
+ },
"node_modules/htm": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/htm/-/htm-3.1.1.tgz",
"integrity": "sha512-983Vyg8NwUE7JkZ6NmOqpCZ+sh1bKv2iYTlUkzlWmA5JD2acKoxd4KVxbMmxX/85mtfdnDmTFoNKcg5DGAvxNQ==",
"license": "Apache-2.0"
},
+ "node_modules/https-proxy-agent": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
+ "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/ignore": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
@@ -3877,7 +4260,6 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
"integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
- "dev": true,
"license": "MIT",
"bin": {
"jsesc": "bin/jsesc"
@@ -3911,7 +4293,6 @@
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
- "dev": true,
"license": "MIT",
"bin": {
"json5": "lib/cli.js"
@@ -3966,7 +4347,6 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
"integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"p-locate": "^5.0.0"
@@ -4001,7 +4381,6 @@
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
- "dev": true,
"license": "ISC",
"dependencies": {
"yallist": "^3.0.2"
@@ -4016,6 +4395,18 @@
"react": "^16.5.1 || ^17.0.0 || ^18.0.0"
}
},
+ "node_modules/magic-string": {
+ "version": "0.30.8",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz",
+ "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.4.15"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
@@ -4067,7 +4458,6 @@
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true,
"license": "MIT"
},
"node_modules/mz": {
@@ -4106,11 +4496,30 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
"node_modules/node-releases": {
"version": "2.0.19",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
"integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
- "dev": true,
"license": "MIT"
},
"node_modules/normalize-path": {
@@ -4182,7 +4591,6 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
"integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"yocto-queue": "^0.1.0"
@@ -4198,7 +4606,6 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
"integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"p-limit": "^3.0.2"
@@ -4233,7 +4640,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -4520,6 +4926,21 @@
"node": ">=6.0.0"
}
},
+ "node_modules/progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+ "license": "MIT"
+ },
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
@@ -4575,6 +4996,12 @@
"react": "^18.3.1"
}
},
+ "node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+ "license": "MIT"
+ },
"node_modules/react-merge-refs": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/react-merge-refs/-/react-merge-refs-1.1.0.tgz",
@@ -5208,6 +5635,12 @@
"node": ">=8.0"
}
},
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+ "license": "MIT"
+ },
"node_modules/ts-api-utils": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz",
@@ -5273,11 +5706,22 @@
"node": ">=14.17"
}
},
+ "node_modules/unplugin": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.0.1.tgz",
+ "integrity": "sha512-aqrHaVBWW1JVKBHmGo33T5TxeL0qWzfvjWokObHA9bYmN7eNDkwOxmLjhioHl9878qDFMAaT51XNroRyuz7WxA==",
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.8.1",
+ "chokidar": "^3.5.3",
+ "webpack-sources": "^3.2.3",
+ "webpack-virtual-modules": "^0.5.0"
+ }
+ },
"node_modules/update-browserslist-db": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
"integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
- "dev": true,
"funding": [
{
"type": "opencollective",
@@ -5437,6 +5881,37 @@
}
}
},
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/webpack-sources": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz",
+ "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/webpack-virtual-modules": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.5.0.tgz",
+ "integrity": "sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==",
+ "license": "MIT"
+ },
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -5567,7 +6042,6 @@
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
- "dev": true,
"license": "ISC"
},
"node_modules/yaml": {
@@ -5586,7 +6060,6 @@
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
diff --git a/frontend/package.json b/frontend/package.json
index 55e44c90..05564075 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -22,6 +22,8 @@
"@radix-ui/react-separator": "^1.1.7",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-tooltip": "^1.2.7",
+ "@sentry/react": "^9.34.0",
+ "@sentry/vite-plugin": "^3.5.0",
"class-variance-authority": "^0.7.0",
"click-to-react-component": "^1.1.2",
"clsx": "^2.0.0",
@@ -50,4 +52,4 @@
"typescript": "^5.2.2",
"vite": "^5.0.8"
}
-}
\ No newline at end of file
+}
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index 9ce4cfde..e16dfec2 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -16,6 +16,9 @@ import type {
ExecutorConfig,
EditorType,
} from 'shared/types';
+import * as Sentry from '@sentry/react';
+
+const SentryRoutes = Sentry.withSentryReactRouterV6Routing(Routes);
function AppContent() {
const { config, updateConfig, loading } = useConfig();
@@ -115,7 +118,7 @@ function AppContent() {
/>
{showNavbar &&