diff --git a/package-lock.json b/package-lock.json index 18fc2f1d..4b09bf24 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "maestro", - "version": "0.8.7", + "version": "0.9.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "maestro", - "version": "0.8.7", + "version": "0.9.1", "hasInstallScript": true, "license": "AGPL 3.0", "dependencies": { @@ -16,6 +16,7 @@ "@fastify/rate-limit": "^9.1.0", "@fastify/static": "^7.0.4", "@fastify/websocket": "^9.0.0", + "@sentry/electron": "^7.5.0", "@tanstack/react-virtual": "^3.13.13", "@types/dompurify": "^3.0.5", "adm-zip": "^0.5.16", @@ -131,6 +132,23 @@ "url": "https://github.com/sponsors/antfu" } }, + "node_modules/@apm-js-collab/code-transformer": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/@apm-js-collab/code-transformer/-/code-transformer-0.8.2.tgz", + "integrity": "sha512-YRjJjNq5KFSjDUoqu5pFUWrrsvGOxl6c3bu+uMFc9HNNptZ2rNU/TI2nLw4jnhQNtka972Ee2m3uqbvDQtPeCA==", + "license": "Apache-2.0" + }, + "node_modules/@apm-js-collab/tracing-hooks": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@apm-js-collab/tracing-hooks/-/tracing-hooks-0.3.1.tgz", + "integrity": "sha512-Vu1CbmPURlN5fTboVuKMoJjbO5qcq9fA5YXpskx3dXe/zTBvjODFoerw+69rVBlRLrJpwPqSDqEuJDEKIrTldw==", + "license": "Apache-2.0", + "dependencies": { + "@apm-js-collab/code-transformer": "^0.8.0", + "debug": "^4.4.1", + "module-details-from-path": "^1.0.4" + } + }, "node_modules/@asamuzakjp/css-color": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-4.1.0.tgz", @@ -1937,6 +1955,505 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/api-logs": { + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.208.0.tgz", + "integrity": "sha512-CjruKY9V6NMssL/T1kAFgzosF1v9o6oeN+aX5JB/C/xPNtmgIJqcXHG7fA82Ou1zCpWGl4lROQUKwUNE1pMCyg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/context-async-hooks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-2.2.0.tgz", + "integrity": "sha512-qRkLWiUEZNAmYapZ7KGS5C4OmBLcP/H2foXeOEaowYCR0wi89fHejrfYfbuLVCMLp/dWZXKvQusdbUEZjERfwQ==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/core": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.2.0.tgz", + "integrity": "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/instrumentation": { + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.208.0.tgz", + "integrity": "sha512-Eju0L4qWcQS+oXxi6pgh7zvE2byogAkcsVv0OjHF/97iOz1N/aKE6etSGowYkie+YA1uo6DNwdSxaaNnLvcRlA==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/api-logs": "0.208.0", + "import-in-the-middle": "^2.0.0", + "require-in-the-middle": "^8.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-amqplib": { + "version": "0.55.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-amqplib/-/instrumentation-amqplib-0.55.0.tgz", + "integrity": "sha512-5ULoU8p+tWcQw5PDYZn8rySptGSLZHNX/7srqo2TioPnAAcvTy6sQFQXsNPrAnyRRtYGMetXVyZUy5OaX1+IfA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-connect": { + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-connect/-/instrumentation-connect-0.52.0.tgz", + "integrity": "sha512-GXPxfNB5szMbV3I9b7kNWSmQBoBzw7MT0ui6iU/p+NIzVx3a06Ri2cdQO7tG9EKb4aKSLmfX9Cw5cKxXqX6Ohg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/connect": "3.4.38" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-dataloader": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-dataloader/-/instrumentation-dataloader-0.26.0.tgz", + "integrity": "sha512-P2BgnFfTOarZ5OKPmYfbXfDFjQ4P9WkQ1Jji7yH5/WwB6Wm/knynAoA1rxbjWcDlYupFkyT0M1j6XLzDzy0aCA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.208.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-express": { + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-express/-/instrumentation-express-0.57.0.tgz", + "integrity": "sha512-HAdx/o58+8tSR5iW+ru4PHnEejyKrAy9fYFhlEI81o10nYxrGahnMAHWiSjhDC7UQSY3I4gjcPgSKQz4rm/asg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fs": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fs/-/instrumentation-fs-0.28.0.tgz", + "integrity": "sha512-FFvg8fq53RRXVBRHZViP+EMxMR03tqzEGpuq55lHNbVPyFklSVfQBN50syPhK5UYYwaStx0eyCtHtbRreusc5g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-generic-pool": { + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-generic-pool/-/instrumentation-generic-pool-0.52.0.tgz", + "integrity": "sha512-ISkNcv5CM2IwvsMVL31Tl61/p2Zm2I2NAsYq5SSBgOsOndT0TjnptjufYVScCnD5ZLD1tpl4T3GEYULLYOdIdQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.208.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-graphql": { + "version": "0.56.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-graphql/-/instrumentation-graphql-0.56.0.tgz", + "integrity": "sha512-IPvNk8AFoVzTAM0Z399t34VDmGDgwT6rIqCUug8P9oAGerl2/PEIYMPOl/rerPGu+q8gSWdmbFSjgg7PDVRd3Q==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.208.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-hapi": { + "version": "0.55.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-hapi/-/instrumentation-hapi-0.55.0.tgz", + "integrity": "sha512-prqAkRf9e4eEpy4G3UcR32prKE8NLNlA90TdEU1UsghOTg0jUvs40Jz8LQWFEs5NbLbXHYGzB4CYVkCI8eWEVQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-http": { + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-http/-/instrumentation-http-0.208.0.tgz", + "integrity": "sha512-rhmK46DRWEbQQB77RxmVXGyjs6783crXCnFjYQj+4tDH/Kpv9Rbg3h2kaNyp5Vz2emF1f9HOQQvZoHzwMWOFZQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.2.0", + "@opentelemetry/instrumentation": "0.208.0", + "@opentelemetry/semantic-conventions": "^1.29.0", + "forwarded-parse": "2.1.2" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-ioredis": { + "version": "0.56.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-ioredis/-/instrumentation-ioredis-0.56.0.tgz", + "integrity": "sha512-XSWeqsd3rKSsT3WBz/JKJDcZD4QYElZEa0xVdX8f9dh4h4QgXhKRLorVsVkK3uXFbC2sZKAS2Ds+YolGwD83Dg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/redis-common": "^0.38.2" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-kafkajs": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-kafkajs/-/instrumentation-kafkajs-0.18.0.tgz", + "integrity": "sha512-KCL/1HnZN5zkUMgPyOxfGjLjbXjpd4odDToy+7c+UsthIzVLFf99LnfIBE8YSSrYE4+uS7OwJMhvhg3tWjqMBg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.30.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-knex": { + "version": "0.53.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-knex/-/instrumentation-knex-0.53.0.tgz", + "integrity": "sha512-xngn5cH2mVXFmiT1XfQ1aHqq1m4xb5wvU6j9lSgLlihJ1bXzsO543cpDwjrZm2nMrlpddBf55w8+bfS4qDh60g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.33.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-koa": { + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-koa/-/instrumentation-koa-0.57.0.tgz", + "integrity": "sha512-3JS8PU/D5E3q295mwloU2v7c7/m+DyCqdu62BIzWt+3u9utjxC9QS7v6WmUNuoDN3RM+Q+D1Gpj13ERo+m7CGg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.36.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0" + } + }, + "node_modules/@opentelemetry/instrumentation-lru-memoizer": { + "version": "0.53.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-lru-memoizer/-/instrumentation-lru-memoizer-0.53.0.tgz", + "integrity": "sha512-LDwWz5cPkWWr0HBIuZUjslyvijljTwmwiItpMTHujaULZCxcYE9eU44Qf/pbVC8TulT0IhZi+RoGvHKXvNhysw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.208.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongodb": { + "version": "0.61.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongodb/-/instrumentation-mongodb-0.61.0.tgz", + "integrity": "sha512-OV3i2DSoY5M/pmLk+68xr5RvkHU8DRB3DKMzYJdwDdcxeLs62tLbkmRyqJZsYf3Ht7j11rq35pHOWLuLzXL7pQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.208.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongoose": { + "version": "0.55.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongoose/-/instrumentation-mongoose-0.55.0.tgz", + "integrity": "sha512-5afj0HfF6aM6Nlqgu6/PPHFk8QBfIe3+zF9FGpX76jWPS0/dujoEYn82/XcLSaW5LPUDW8sni+YeK0vTBNri+w==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql": { + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql/-/instrumentation-mysql-0.54.0.tgz", + "integrity": "sha512-bqC1YhnwAeWmRzy1/Xf9cDqxNG2d/JDkaxnqF5N6iJKN1eVWI+vg7NfDkf52/Nggp3tl1jcC++ptC61BD6738A==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.208.0", + "@types/mysql": "2.15.27" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql2": { + "version": "0.55.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql2/-/instrumentation-mysql2-0.55.0.tgz", + "integrity": "sha512-0cs8whQG55aIi20gnK8B7cco6OK6N+enNhW0p5284MvqJ5EPi+I1YlWsWXgzv/V2HFirEejkvKiI4Iw21OqDWg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.33.0", + "@opentelemetry/sql-common": "^0.41.2" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-pg": { + "version": "0.61.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.61.0.tgz", + "integrity": "sha512-UeV7KeTnRSM7ECHa3YscoklhUtTQPs6V6qYpG283AB7xpnPGCUCUfECFT9jFg6/iZOQTt3FHkB1wGTJCNZEvPw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.34.0", + "@opentelemetry/sql-common": "^0.41.2", + "@types/pg": "8.15.6", + "@types/pg-pool": "2.0.6" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-redis": { + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-redis/-/instrumentation-redis-0.57.0.tgz", + "integrity": "sha512-bCxTHQFXzrU3eU1LZnOZQ3s5LURxQPDlU3/upBzlWY77qOI1GZuGofazj3jtzjctMJeBEJhNwIFEgRPBX1kp/Q==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/redis-common": "^0.38.2", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-tedious": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-tedious/-/instrumentation-tedious-0.27.0.tgz", + "integrity": "sha512-jRtyUJNZppPBjPae4ZjIQ2eqJbcRaRfJkr0lQLHFmOU/no5A6e9s1OHLd5XZyZoBJ/ymngZitanyRRA5cniseA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.208.0", + "@types/tedious": "^4.0.14" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-undici": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-undici/-/instrumentation-undici-0.19.0.tgz", + "integrity": "sha512-Pst/RhR61A2OoZQZkn6OLpdVpXp6qn3Y92wXa6umfJe9rV640r4bc6SWvw4pPN6DiQqPu2c8gnSSZPDtC6JlpQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.24.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.7.0" + } + }, + "node_modules/@opentelemetry/redis-common": { + "version": "0.38.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/redis-common/-/redis-common-0.38.2.tgz", + "integrity": "sha512-1BCcU93iwSRZvDAgwUxC/DV4T/406SkMfxGqu5ojc3AvNI+I9GhV7v0J1HljsczuuhcnFLYqD5VmwVXfCGHzxA==", + "license": "Apache-2.0", + "engines": { + "node": "^18.19.0 || >=20.6.0" + } + }, + "node_modules/@opentelemetry/resources": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.2.0.tgz", + "integrity": "sha512-1pNQf/JazQTMA0BiO5NINUzH0cbLbbl7mntLa4aJNmCCXSj0q03T5ZXXL0zw4G55TjdL9Tz32cznGClf+8zr5A==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/core": "2.2.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-base": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.2.0.tgz", + "integrity": "sha512-xWQgL0Bmctsalg6PaXExmzdedSp3gyKV8mQBwK/j9VGdCDu2fmXIb2gAehBKbkXCpJ4HPkgv3QfoJWRT4dHWbw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/core": "2.2.0", + "@opentelemetry/resources": "2.2.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.38.0.tgz", + "integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sql-common": { + "version": "0.41.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/sql-common/-/sql-common-0.41.2.tgz", + "integrity": "sha512-4mhWm3Z8z+i508zQJ7r6Xi7y4mmoJpdvH0fZPFRkWrdp5fq7hhZ2HhYokEOLkfqSMgPR4Z9EyB3DBkbKGOqZiQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0" + } + }, "node_modules/@pinojs/redact": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/@pinojs/redact/-/redact-0.4.0.tgz", @@ -1969,6 +2486,18 @@ "node": ">=18" } }, + "node_modules/@prisma/instrumentation": { + "version": "6.19.0", + "resolved": "https://registry.npmjs.org/@prisma/instrumentation/-/instrumentation-6.19.0.tgz", + "integrity": "sha512-QcuYy25pkXM8BJ37wVFBO7Zh34nyRV1GOb2n3lPkkbRYfl4hWl3PTcImP41P0KrzVXfa/45p6eVCos27x3exIg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": ">=0.52.0 <1" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.8" + } + }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-beta.27", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", @@ -2284,6 +2813,204 @@ "win32" ] }, + "node_modules/@sentry-internal/browser-utils": { + "version": "10.29.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-10.29.0.tgz", + "integrity": "sha512-M3kycMY6f3KY9a8jDYac+yG0E3ZgWVWSxlOEC5MhYyX+g7mqxkwrb3LFQyuxSm/m+CCgMTCaPOOaB2twXP6EQg==", + "license": "MIT", + "dependencies": { + "@sentry/core": "10.29.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry-internal/feedback": { + "version": "10.29.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-10.29.0.tgz", + "integrity": "sha512-Y7IRsNeS99cEONu1mZWZc3HvbjNnu59Hgymm0swFFKbdgbCgdT6l85kn2oLsuq4Ew8Dw/pL/Sgpwsl9UgYFpUg==", + "license": "MIT", + "dependencies": { + "@sentry/core": "10.29.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry-internal/replay": { + "version": "10.29.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-10.29.0.tgz", + "integrity": "sha512-45NVw9PwB9TQ8z+xJ6G6Za+wmQ1RTA35heBSzR6U4bknj8LmA04k2iwnobvxCBEQXeLfcJEO1vFgagMoqMZMBw==", + "license": "MIT", + "dependencies": { + "@sentry-internal/browser-utils": "10.29.0", + "@sentry/core": "10.29.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry-internal/replay-canvas": { + "version": "10.29.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-10.29.0.tgz", + "integrity": "sha512-typY4JrpAQQGPuSyd/BD8+nNCbvTV2UVvKzr+iKgI0m1qc4Dz8tHZ4Nfais2Z8eYn/pL1kqVQN5ERTmJoYFdIw==", + "license": "MIT", + "dependencies": { + "@sentry-internal/replay": "10.29.0", + "@sentry/core": "10.29.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/browser": { + "version": "10.29.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-10.29.0.tgz", + "integrity": "sha512-XdbyIR6F4qoR9Z1JCWTgunVcTJjS9p2Th+v4wYs4ME+ZdLC4tuKKmRgYg3YdSIWCn1CBfIgdI6wqETSf7H6Njw==", + "license": "MIT", + "dependencies": { + "@sentry-internal/browser-utils": "10.29.0", + "@sentry-internal/feedback": "10.29.0", + "@sentry-internal/replay": "10.29.0", + "@sentry-internal/replay-canvas": "10.29.0", + "@sentry/core": "10.29.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/core": { + "version": "10.29.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.29.0.tgz", + "integrity": "sha512-olQ2DU9dA/Bwsz3PtA9KNXRMqBWRQSkPw+MxwWEoU1K1qtiM9L0j6lbEFb5iSY3d7WYD5MB+1d5COugjSBrHtw==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/electron": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@sentry/electron/-/electron-7.5.0.tgz", + "integrity": "sha512-88t/YsB5iO75faKdd7lIuJkwp9FGKgFlkDuaSJhsJiVcjlywkn8CwUbctAbS0gu6Suc0raHCF4ULvGyksKAoww==", + "license": "MIT", + "dependencies": { + "@sentry/browser": "10.29.0", + "@sentry/core": "10.29.0", + "@sentry/node": "10.29.0" + }, + "peerDependencies": { + "@sentry/node-native": "10.29.0" + }, + "peerDependenciesMeta": { + "@sentry/node-native": { + "optional": true + } + } + }, + "node_modules/@sentry/node": { + "version": "10.29.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-10.29.0.tgz", + "integrity": "sha512-9j8VzV06VCj+H8tlxpfa7BNN4HzH5exv68WOufdMTXzzWLOXnzrdNDoYplm1G2S3LMvWsc1SVI3a8A0yBY7oWg==", + "license": "MIT", + "dependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^2.2.0", + "@opentelemetry/core": "^2.2.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/instrumentation-amqplib": "0.55.0", + "@opentelemetry/instrumentation-connect": "0.52.0", + "@opentelemetry/instrumentation-dataloader": "0.26.0", + "@opentelemetry/instrumentation-express": "0.57.0", + "@opentelemetry/instrumentation-fs": "0.28.0", + "@opentelemetry/instrumentation-generic-pool": "0.52.0", + "@opentelemetry/instrumentation-graphql": "0.56.0", + "@opentelemetry/instrumentation-hapi": "0.55.0", + "@opentelemetry/instrumentation-http": "0.208.0", + "@opentelemetry/instrumentation-ioredis": "0.56.0", + "@opentelemetry/instrumentation-kafkajs": "0.18.0", + "@opentelemetry/instrumentation-knex": "0.53.0", + "@opentelemetry/instrumentation-koa": "0.57.0", + "@opentelemetry/instrumentation-lru-memoizer": "0.53.0", + "@opentelemetry/instrumentation-mongodb": "0.61.0", + "@opentelemetry/instrumentation-mongoose": "0.55.0", + "@opentelemetry/instrumentation-mysql": "0.54.0", + "@opentelemetry/instrumentation-mysql2": "0.55.0", + "@opentelemetry/instrumentation-pg": "0.61.0", + "@opentelemetry/instrumentation-redis": "0.57.0", + "@opentelemetry/instrumentation-tedious": "0.27.0", + "@opentelemetry/instrumentation-undici": "0.19.0", + "@opentelemetry/resources": "^2.2.0", + "@opentelemetry/sdk-trace-base": "^2.2.0", + "@opentelemetry/semantic-conventions": "^1.37.0", + "@prisma/instrumentation": "6.19.0", + "@sentry/core": "10.29.0", + "@sentry/node-core": "10.29.0", + "@sentry/opentelemetry": "10.29.0", + "import-in-the-middle": "^2", + "minimatch": "^9.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/node-core": { + "version": "10.29.0", + "resolved": "https://registry.npmjs.org/@sentry/node-core/-/node-core-10.29.0.tgz", + "integrity": "sha512-f/Y0okHhPPb5HnYNBqCivJ2YuXtSadvcIx16dzU5mHQxZhgGednUCPEX7rsvPcd4HneQz12HKLqxbAmNu+b3FA==", + "license": "MIT", + "dependencies": { + "@apm-js-collab/tracing-hooks": "^0.3.1", + "@sentry/core": "10.29.0", + "@sentry/opentelemetry": "10.29.0", + "import-in-the-middle": "^2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.1.0 || ^2.2.0", + "@opentelemetry/core": "^1.30.1 || ^2.1.0 || ^2.2.0", + "@opentelemetry/instrumentation": ">=0.57.1 <1", + "@opentelemetry/resources": "^1.30.1 || ^2.1.0 || ^2.2.0", + "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0 || ^2.2.0", + "@opentelemetry/semantic-conventions": "^1.37.0" + } + }, + "node_modules/@sentry/node/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@sentry/opentelemetry": { + "version": "10.29.0", + "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-10.29.0.tgz", + "integrity": "sha512-5QvtAwS73HlI/+OTF1poAFELzsc0se+PHmMsXGGrOeNBvjCr3ZE8qvke09aeMn7uRImf3Nc9J6i2KtSHJnbKPA==", + "license": "MIT", + "dependencies": { + "@sentry/core": "10.29.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.1.0 || ^2.2.0", + "@opentelemetry/core": "^1.30.1 || ^2.1.0 || ^2.2.0", + "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0 || ^2.2.0", + "@opentelemetry/semantic-conventions": "^1.37.0" + } + }, "node_modules/@sindresorhus/is": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", @@ -2533,6 +3260,15 @@ "assertion-error": "^2.0.1" } }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/d3": { "version": "7.4.3", "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", @@ -2883,16 +3619,44 @@ "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", "license": "MIT" }, + "node_modules/@types/mysql": { + "version": "2.15.27", + "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.27.tgz", + "integrity": "sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/node": { "version": "20.19.25", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.25.tgz", "integrity": "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==", - "dev": true, "license": "MIT", "dependencies": { "undici-types": "~6.21.0" } }, + "node_modules/@types/pg": { + "version": "8.15.6", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.15.6.tgz", + "integrity": "sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^2.2.0" + } + }, + "node_modules/@types/pg-pool": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/pg-pool/-/pg-pool-2.0.6.tgz", + "integrity": "sha512-TaAUE5rq2VQYxab5Ts7WZhKNmuN78Q6PiFonTDdpbx8a1H0M1vhy3rhiMjl+e2iHmogyMw7jZF4FrE6eJUy5HQ==", + "license": "MIT", + "dependencies": { + "@types/pg": "*" + } + }, "node_modules/@types/plist": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.5.tgz", @@ -2979,6 +3743,15 @@ "@types/node": "*" } }, + "node_modules/@types/tedious": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/@types/tedious/-/tedious-4.0.14.tgz", + "integrity": "sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/trusted-types": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", @@ -3210,6 +3983,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3217,6 +3991,15 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^8" + } + }, "node_modules/adm-zip": { "version": "0.5.16", "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.16.tgz", @@ -4624,6 +5407,12 @@ "node": ">=8" } }, + "node_modules/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "license": "MIT" + }, "node_modules/classnames": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", @@ -7447,6 +8236,12 @@ "node": ">= 0.6" } }, + "node_modules/forwarded-parse": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/forwarded-parse/-/forwarded-parse-2.1.2.tgz", + "integrity": "sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==", + "license": "MIT" + }, "node_modules/fraction.js": { "version": "5.3.4", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", @@ -8281,6 +9076,18 @@ ], "license": "BSD-3-Clause" }, + "node_modules/import-in-the-middle": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-2.0.0.tgz", + "integrity": "sha512-yNZhyQYqXpkT0AKq3F3KLasUSK4fHvebNH5hOsKQw2dhGSALvQ4U0BqUc5suziKvydO5u5hgN2hy1RJaho8U5A==", + "license": "Apache-2.0", + "dependencies": { + "acorn": "^8.14.0", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -10711,6 +11518,12 @@ "obliterator": "^2.0.1" } }, + "node_modules/module-details-from-path": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.4.tgz", + "integrity": "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==", + "license": "MIT" + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -11276,6 +12089,37 @@ "dev": true, "license": "MIT" }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.3.tgz", + "integrity": "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==", + "license": "MIT" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -11643,6 +12487,45 @@ "dev": true, "license": "MIT" }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", + "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/prebuild-install": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", @@ -12349,6 +13232,19 @@ "node": ">=0.10.0" } }, + "node_modules/require-in-the-middle": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-8.0.1.tgz", + "integrity": "sha512-QT7FVMXfWOYFbeRBF6nu+I6tr2Tf3u0q8RIEjNob/heKY/nh7drD/k7eeMFmSQgnTtCzLDcCu/XEnpW2wk4xCQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "module-details-from-path": "^1.0.3" + }, + "engines": { + "node": ">=9.3.0 || >=8.10.0 <9.0.0" + } + }, "node_modules/require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -13788,7 +14684,6 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "dev": true, "license": "MIT" }, "node_modules/unified": { @@ -15502,6 +16397,15 @@ "dev": true, "license": "MIT" }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index cdaac911..f90b66ed 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "maestro", - "version": "0.9.0", + "version": "0.9.1", "description": "Run AI coding agents autonomously for days.", "main": "dist/main/index.js", "author": { @@ -150,6 +150,7 @@ "@fastify/rate-limit": "^9.1.0", "@fastify/static": "^7.0.4", "@fastify/websocket": "^9.0.0", + "@sentry/electron": "^7.5.0", "@tanstack/react-virtual": "^3.13.13", "@types/dompurify": "^3.0.5", "adm-zip": "^0.5.16", diff --git a/src/__tests__/renderer/components/QuickActionsModal.test.tsx b/src/__tests__/renderer/components/QuickActionsModal.test.tsx index ab8e7b6a..6a8382bf 100644 --- a/src/__tests__/renderer/components/QuickActionsModal.test.tsx +++ b/src/__tests__/renderer/components/QuickActionsModal.test.tsx @@ -785,10 +785,12 @@ describe('QuickActionsModal', () => { }); render(); + // Filter to just sessions so we can reliably test Cmd+0 const input = screen.getByPlaceholderText('Type a command or jump to agent...'); + fireEvent.change(input, { target: { value: 'Session' } }); fireEvent.keyDown(input, { key: '0', metaKey: true }); - // Should trigger the 10th item + // Should trigger the 10th session (Session 9 due to alphabetical sorting) expect(props.setActiveSessionId).toHaveBeenCalled(); }); }); diff --git a/src/main/agent-detector.ts b/src/main/agent-detector.ts index 86f596fa..c4011143 100644 --- a/src/main/agent-detector.ts +++ b/src/main/agent-detector.ts @@ -62,6 +62,7 @@ const AGENT_DEFINITIONS: Omit ['--resume', sessionId], // Resume with session ID + readOnlyArgs: ['--permission-mode', 'plan'], // Read-only/plan mode }, { id: 'codex', diff --git a/src/main/index.ts b/src/main/index.ts index a40de6fe..db9612eb 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -3,6 +3,7 @@ import path from 'path'; import os from 'os'; import fs from 'fs/promises'; import fsSync from 'fs'; +import * as Sentry from '@sentry/electron/main'; import { ProcessManager } from './process-manager'; import { WebServer } from './web-server'; import { AgentDetector } from './agent-detector'; @@ -17,6 +18,32 @@ import { initializeOutputParsers } from './parsers'; import { DEMO_MODE, DEMO_DATA_PATH } from './constants'; import { initAutoUpdater } from './auto-updater'; +// Initialize Sentry for crash reporting (before app.ready) +// Check if crash reporting is enabled (default: true for opt-out behavior) +const crashReportingStore = new Store<{ crashReportingEnabled: boolean }>({ + name: 'maestro-settings', +}); +const crashReportingEnabled = crashReportingStore.get('crashReportingEnabled', true); + +if (crashReportingEnabled) { + Sentry.init({ + dsn: 'https://2303c5f787f910863d83ed5d27ce8ed2@o4510554134740992.ingest.us.sentry.io/4510554135789568', + // Set release version for better debugging + release: app.getVersion(), + // Only send errors, not performance data + tracesSampleRate: 0, + // Filter out sensitive data + beforeSend(event) { + // Remove any potential sensitive data from the event + if (event.user) { + delete event.user.ip_address; + delete event.user.email; + } + return event; + }, + }); +} + // Demo mode: use a separate data directory for fresh demos if (DEMO_MODE) { app.setPath('userData', DEMO_DATA_PATH); diff --git a/src/main/ipc/handlers/process.ts b/src/main/ipc/handlers/process.ts index 23398be8..0de39013 100644 --- a/src/main/ipc/handlers/process.ts +++ b/src/main/ipc/handlers/process.ts @@ -94,7 +94,10 @@ export function registerProcessHandlers(deps: ProcessHandlerDependencies): void agentId: agent?.id, agentCommand: agent?.command, agentPath: agent?.path, - hasAgentSessionId: !!config.agentSessionId + hasAgentSessionId: !!config.agentSessionId, + hasPrompt: !!config.prompt, + promptLength: config.prompt?.length, + promptValue: config.prompt, }); let finalArgs = [...config.args]; diff --git a/src/renderer/App.tsx b/src/renderer/App.tsx index 0cfb7bc9..92ab40f1 100644 --- a/src/renderer/App.tsx +++ b/src/renderer/App.tsx @@ -179,6 +179,7 @@ export default function MaestroConsole() { audioFeedbackCommand, setAudioFeedbackCommand, toastDuration, setToastDuration, checkForUpdatesOnStartup, setCheckForUpdatesOnStartup, + crashReportingEnabled, setCrashReportingEnabled, shortcuts, setShortcuts, customAICommands, setCustomAICommands, globalStats, updateGlobalStats, @@ -1671,12 +1672,9 @@ export default function MaestroConsole() { // Create a new tab in the session to start fresh setSessions(prev => prev.map(s => { if (s.id !== sessionId) return s; - const newTab = createTab(); - return { - ...s, - aiTabs: [...s.aiTabs, newTab], - activeTabId: newTab.id, - }; + const result = createTab(s); + if (!result) return s; + return result.session; })); // Focus the input after creating new tab @@ -3434,8 +3432,8 @@ export default function MaestroConsole() { return; } - // Build spawn args with resume if we have an agent session ID - // Use the ACTIVE TAB's agentSessionId (not the deprecated session-level one) + // Get the ACTIVE TAB's agentSessionId for session continuity + // (not the deprecated session-level one) const activeTab = getActiveTab(session); const tabAgentSessionId = activeTab?.agentSessionId; const isReadOnly = activeTab?.readOnlyMode; @@ -3451,14 +3449,9 @@ export default function MaestroConsole() { ) : [...agent.args]; - if (tabAgentSessionId) { - spawnArgs.push('--resume', tabAgentSessionId); - } - - // Add read-only/plan mode if the active tab has readOnlyMode enabled - if (isReadOnly) { - spawnArgs.push('--permission-mode', 'plan'); - } + // Note: agentSessionId and readOnlyMode are passed to spawn() config below. + // The main process uses agent-specific argument builders (resumeArgs, readOnlyArgs) + // to construct the correct CLI args for each agent type. // Include tab ID in targetSessionId for proper output routing const targetSessionId = `${sessionId}-ai-${activeTab?.id || 'default'}`; @@ -3526,7 +3519,10 @@ export default function MaestroConsole() { cwd: session.cwd, command: commandToUse, args: spawnArgs, - prompt: promptToSend + prompt: promptToSend, + // Generic spawn options - main process builds agent-specific args + agentSessionId: tabAgentSessionId, + readOnlyMode: isReadOnly, }); console.log(`[Remote] ${session.toolType} spawn initiated successfully`); @@ -3618,8 +3614,8 @@ export default function MaestroConsole() { const agent = await window.maestro.agents.get(session.toolType); if (!agent) throw new Error(`Agent not found for toolType: ${session.toolType}`); - // Build spawn args with resume if we have a session ID - // Use the TARGET TAB's agentSessionId (not the active tab or deprecated session-level one) + // Get the TARGET TAB's agentSessionId for session continuity + // (not the active tab or deprecated session-level one) const tabAgentSessionId = targetTab?.agentSessionId; const isReadOnly = item.readOnlyMode || targetTab?.readOnlyMode; @@ -3634,15 +3630,9 @@ export default function MaestroConsole() { ) : [...(agent.args || [])]; - if (tabAgentSessionId) { - spawnArgs.push('--resume', tabAgentSessionId); - } - - // Add read-only/plan mode if the queued item was from a read-only tab - // or if the target tab currently has readOnlyMode enabled - if (isReadOnly) { - spawnArgs.push('--permission-mode', 'plan'); - } + // Note: agentSessionId and readOnlyMode are passed to spawn() config below. + // The main process uses agent-specific argument builders (resumeArgs, readOnlyArgs) + // to construct the correct CLI args for each agent type. const commandToUse = agent.path || agent.command; @@ -3656,6 +3646,18 @@ export default function MaestroConsole() { // If user sends only an image without text, inject the default image-only prompt const effectivePrompt = isImageOnlyMessage ? DEFAULT_IMAGE_ONLY_PROMPT : item.text!; + console.log('[processQueuedItem] Spawning agent with queued message:', { + sessionId: targetSessionId, + toolType: session.toolType, + prompt: effectivePrompt, + promptLength: effectivePrompt?.length, + hasAgentSessionId: !!tabAgentSessionId, + agentSessionId: tabAgentSessionId, + isReadOnly, + argsLength: spawnArgs.length, + args: spawnArgs, + }); + await window.maestro.process.spawn({ sessionId: targetSessionId, toolType: session.toolType, @@ -3663,7 +3665,10 @@ export default function MaestroConsole() { command: commandToUse, args: spawnArgs, prompt: effectivePrompt, - images: hasImages ? item.images : undefined + images: hasImages ? item.images : undefined, + // Generic spawn options - main process builds agent-specific args + agentSessionId: tabAgentSessionId, + readOnlyMode: isReadOnly, }); } else if (item.type === 'command' && item.command) { // Process a slash command - find the matching custom AI command @@ -3711,7 +3716,10 @@ export default function MaestroConsole() { cwd: session.cwd, command: commandToUse, args: spawnArgs, - prompt: substitutedPrompt + prompt: substitutedPrompt, + // Generic spawn options - main process builds agent-specific args + agentSessionId: tabAgentSessionId, + readOnlyMode: isReadOnly, }); } else { // Unknown command - add error log @@ -4775,6 +4783,10 @@ export default function MaestroConsole() { setTourOpen(true); }} setFuzzyFileSearchOpen={setFuzzyFileSearchOpen} + onEditAgent={(session) => { + setEditAgentSession(session); + setEditAgentModalOpen(true); + }} /> )} {lightboxImage && ( @@ -5179,6 +5191,7 @@ export default function MaestroConsole() { setSessions(prev => prev.map(s => { if (s.id !== activeSession.id) return s; const result = createTab(s, { saveToHistory: defaultSaveToHistory }); + if (!result) return s; return result.session; })); setActiveAgentSessionId(null); @@ -5377,6 +5390,7 @@ export default function MaestroConsole() { setSessions(prev => prev.map(s => { if (s.id !== activeSession.id) return s; const result = createTab(s, { saveToHistory: defaultSaveToHistory }); + if (!result) return s; return result.session; })); }} @@ -5963,6 +5977,8 @@ export default function MaestroConsole() { setToastDuration={setToastDuration} checkForUpdatesOnStartup={checkForUpdatesOnStartup} setCheckForUpdatesOnStartup={setCheckForUpdatesOnStartup} + crashReportingEnabled={crashReportingEnabled} + setCrashReportingEnabled={setCrashReportingEnabled} customAICommands={customAICommands} setCustomAICommands={setCustomAICommands} initialTab={settingsTab} diff --git a/src/renderer/components/QueuedItemsList.tsx b/src/renderer/components/QueuedItemsList.tsx index ef9f6ab4..de681f04 100644 --- a/src/renderer/components/QueuedItemsList.tsx +++ b/src/renderer/components/QueuedItemsList.tsx @@ -16,7 +16,7 @@ interface QueuedItemsListProps { /** * QueuedItemsList displays the execution queue with: * - Queued message separator with count - * - Individual queued items (commands/messages) with tab indicators + * - Individual queued items (commands/messages) * - Long message expand/collapse functionality * - Image attachment indicators * - Remove button with confirmation modal @@ -117,16 +117,6 @@ export const QueuedItemsList = memo(({ - {/* Tab indicator */} - {item.tabName && ( -
- → {item.tabName} -
- )} - {/* Item content */}
void; startTour?: () => void; setFuzzyFileSearchOpen?: (open: boolean) => void; + onEditAgent?: (session: Session) => void; } export function QuickActionsModal(props: QuickActionsModalProps) { @@ -82,7 +83,7 @@ export function QuickActionsModal(props: QuickActionsModalProps) { setShortcutsHelpOpen, setAboutModalOpen, setLogViewerOpen, setProcessMonitorOpen, setAgentSessionsOpen, setActiveAgentSessionId, setGitDiffPreview, setGitLogOpen, onRenameTab, onToggleReadOnlyMode, onOpenTabSwitcher, tabShortcuts, isAiMode, setPlaygroundOpen, onRefreshGitFileState, - onDebugReleaseQueuedItem, markdownEditMode, onToggleMarkdownEditMode, setUpdateCheckModalOpen, openWizard, wizardGoToStep, setDebugWizardModalOpen, startTour, setFuzzyFileSearchOpen + onDebugReleaseQueuedItem, markdownEditMode, onToggleMarkdownEditMode, setUpdateCheckModalOpen, openWizard, wizardGoToStep, setDebugWizardModalOpen, startTour, setFuzzyFileSearchOpen, onEditAgent } = props; const [search, setSearch] = useState(''); @@ -204,6 +205,16 @@ export function QuickActionsModal(props: QuickActionsModalProps) { setRenameInstanceModalOpen(true); setQuickActionOpen(false); } }] : []), + ...(activeSession && onEditAgent ? [{ id: 'editAgent', label: `Edit Agent: ${activeSession.name}`, action: () => { + onEditAgent(activeSession); + setQuickActionOpen(false); + } }] : []), + ...(activeSession ? [{ id: 'toggleBookmark', label: activeSession.bookmarked ? `Unbookmark: ${activeSession.name}` : `Bookmark: ${activeSession.name}`, action: () => { + setSessions(prev => prev.map(s => + s.id === activeSessionId ? { ...s, bookmarked: !s.bookmarked } : s + )); + setQuickActionOpen(false); + } }] : []), ...(activeSession?.groupId ? [{ id: 'renameGroup', label: 'Rename Group', diff --git a/src/renderer/components/SettingsModal.tsx b/src/renderer/components/SettingsModal.tsx index e6bf78cd..704bd7f6 100644 --- a/src/renderer/components/SettingsModal.tsx +++ b/src/renderer/components/SettingsModal.tsx @@ -1,5 +1,5 @@ import React, { useState, useEffect, useRef, memo } from 'react'; -import { X, Key, Moon, Sun, Keyboard, Check, Terminal, Bell, Cpu, Settings, Palette, Sparkles, History, Download } from 'lucide-react'; +import { X, Key, Moon, Sun, Keyboard, Check, Terminal, Bell, Cpu, Settings, Palette, Sparkles, History, Download, Bug } from 'lucide-react'; import type { AgentConfig, Theme, ThemeColors, ThemeId, Shortcut, ShellInfo, CustomAICommand } from '../types'; import { CustomThemeBuilder } from './CustomThemeBuilder'; import { useLayerStack } from '../contexts/LayerStackContext'; @@ -70,6 +70,8 @@ interface SettingsModalProps { setToastDuration: (value: number) => void; checkForUpdatesOnStartup: boolean; setCheckForUpdatesOnStartup: (value: boolean) => void; + crashReportingEnabled: boolean; + setCrashReportingEnabled: (value: boolean) => void; customAICommands: CustomAICommand[]; setCustomAICommands: (commands: CustomAICommand[]) => void; initialTab?: 'general' | 'llm' | 'shortcuts' | 'theme' | 'notifications' | 'aicommands'; @@ -871,6 +873,17 @@ export const SettingsModal = memo(function SettingsModal(props: SettingsModalPro onChange={props.setCheckForUpdatesOnStartup} theme={theme} /> + + {/* Crash Reporting */} +
)} diff --git a/src/renderer/hooks/useAgentExecution.ts b/src/renderer/hooks/useAgentExecution.ts index 63b23b86..939da18a 100644 --- a/src/renderer/hooks/useAgentExecution.ts +++ b/src/renderer/hooks/useAgentExecution.ts @@ -299,17 +299,16 @@ export function useAgentExecution( // Spawn the agent for batch processing // Use effectiveCwd which may be a worktree path for parallel execution const commandToUse = agent.path || agent.command; - // Only add Claude-specific permission-mode flag for Claude Code - const spawnArgs = session.toolType === 'claude-code' - ? [...(agent.args || []), '--permission-mode', 'plan'] - : [...(agent.args || [])]; + // Batch processing runs in read-only mode (plan mode) to prevent unintended writes + // The main process uses agent-specific readOnlyArgs builders for correct CLI args window.maestro.process.spawn({ sessionId: targetSessionId, toolType: session.toolType, cwd: effectiveCwd, command: commandToUse, - args: spawnArgs, - prompt + args: agent.args || [], + prompt, + readOnlyMode: true, // Batch operations run in read-only/plan mode }).catch(() => { cleanup(); resolve({ success: false }); diff --git a/src/renderer/hooks/useAgentSessionManagement.ts b/src/renderer/hooks/useAgentSessionManagement.ts index 66b485de..9a39a514 100644 --- a/src/renderer/hooks/useAgentSessionManagement.ts +++ b/src/renderer/hooks/useAgentSessionManagement.ts @@ -261,15 +261,16 @@ export function useAgentSessionManagement( if (s.id !== activeSession.id) return s; // Create tab from the CURRENT session state (not stale closure value) - const { session: updatedSession } = createTab(s, { + const result = createTab(s, { agentSessionId, logs: messages, name, starred: isStarred, saveToHistory: defaultSaveToHistory }); + if (!result) return s; - return { ...updatedSession, inputMode: 'ai' }; + return { ...result.session, inputMode: 'ai' }; })); setActiveAgentSessionId(agentSessionId); } catch (error) { diff --git a/src/renderer/hooks/useMainKeyboardHandler.ts b/src/renderer/hooks/useMainKeyboardHandler.ts index 7db12f51..e041ee28 100644 --- a/src/renderer/hooks/useMainKeyboardHandler.ts +++ b/src/renderer/hooks/useMainKeyboardHandler.ts @@ -308,12 +308,14 @@ export function useMainKeyboardHandler(): UseMainKeyboardHandlerReturn { if (ctx.isTabShortcut(e, 'newTab')) { e.preventDefault(); const result = ctx.createTab(ctx.activeSession, { saveToHistory: ctx.defaultSaveToHistory }); - ctx.setSessions((prev: Session[]) => prev.map((s: Session) => - s.id === ctx.activeSession!.id ? result.session : s - )); - // Auto-focus the input so user can start typing immediately - ctx.setActiveFocus('main'); - setTimeout(() => ctx.inputRef.current?.focus(), 50); + if (result) { + ctx.setSessions((prev: Session[]) => prev.map((s: Session) => + s.id === ctx.activeSession!.id ? result.session : s + )); + // Auto-focus the input so user can start typing immediately + ctx.setActiveFocus('main'); + setTimeout(() => ctx.inputRef.current?.focus(), 50); + } } if (ctx.isTabShortcut(e, 'closeTab')) { e.preventDefault(); diff --git a/src/renderer/hooks/useRemoteIntegration.ts b/src/renderer/hooks/useRemoteIntegration.ts index 124dde76..e984c4ec 100644 --- a/src/renderer/hooks/useRemoteIntegration.ts +++ b/src/renderer/hooks/useRemoteIntegration.ts @@ -265,6 +265,7 @@ export function useRemoteIntegration(deps: UseRemoteIntegrationDeps): UseRemoteI // Use createTab helper const result = createTab(s, { saveToHistory: defaultSaveToHistory }); + if (!result) return s; newTabId = result.tab.id; return result.session; })); diff --git a/src/renderer/hooks/useSettings.ts b/src/renderer/hooks/useSettings.ts index 0948d3b8..a5dc6fd3 100644 --- a/src/renderer/hooks/useSettings.ts +++ b/src/renderer/hooks/useSettings.ts @@ -152,6 +152,10 @@ export interface UseSettingsReturn { checkForUpdatesOnStartup: boolean; setCheckForUpdatesOnStartup: (value: boolean) => void; + // Crash reporting settings + crashReportingEnabled: boolean; + setCrashReportingEnabled: (value: boolean) => void; + // Log Viewer settings logViewerSelectedLevels: string[]; setLogViewerSelectedLevels: (value: string[]) => void; @@ -272,6 +276,9 @@ export function useSettings(): UseSettingsReturn { // Update Config const [checkForUpdatesOnStartup, setCheckForUpdatesOnStartupState] = useState(true); // Default: on + // Crash Reporting Config + const [crashReportingEnabled, setCrashReportingEnabledState] = useState(true); // Default: on (opt-out) + // Log Viewer Config const [logViewerSelectedLevels, setLogViewerSelectedLevelsState] = useState(['debug', 'info', 'warn', 'error', 'toast']); @@ -453,6 +460,11 @@ export function useSettings(): UseSettingsReturn { window.maestro.settings.set('checkForUpdatesOnStartup', value); }, []); + const setCrashReportingEnabled = useCallback((value: boolean) => { + setCrashReportingEnabledState(value); + window.maestro.settings.set('crashReportingEnabled', value); + }, []); + const setLogViewerSelectedLevels = useCallback((value: string[]) => { setLogViewerSelectedLevelsState(value); window.maestro.settings.set('logViewerSelectedLevels', value); @@ -887,6 +899,7 @@ export function useSettings(): UseSettingsReturn { const savedAudioFeedbackCommand = await window.maestro.settings.get('audioFeedbackCommand'); const savedToastDuration = await window.maestro.settings.get('toastDuration'); const savedCheckForUpdatesOnStartup = await window.maestro.settings.get('checkForUpdatesOnStartup'); + const savedCrashReportingEnabled = await window.maestro.settings.get('crashReportingEnabled'); const savedLogViewerSelectedLevels = await window.maestro.settings.get('logViewerSelectedLevels'); const savedCustomAICommands = await window.maestro.settings.get('customAICommands'); const savedGlobalStats = await window.maestro.settings.get('globalStats'); @@ -929,6 +942,7 @@ export function useSettings(): UseSettingsReturn { if (savedAudioFeedbackCommand !== undefined) setAudioFeedbackCommandState(savedAudioFeedbackCommand); if (savedToastDuration !== undefined) setToastDurationState(savedToastDuration); if (savedCheckForUpdatesOnStartup !== undefined) setCheckForUpdatesOnStartupState(savedCheckForUpdatesOnStartup); + if (savedCrashReportingEnabled !== undefined) setCrashReportingEnabledState(savedCrashReportingEnabled); if (savedLogViewerSelectedLevels !== undefined) setLogViewerSelectedLevelsState(savedLogViewerSelectedLevels); // Merge saved shortcuts with defaults (in case new shortcuts were added) @@ -1113,6 +1127,8 @@ export function useSettings(): UseSettingsReturn { setToastDuration, checkForUpdatesOnStartup, setCheckForUpdatesOnStartup, + crashReportingEnabled, + setCrashReportingEnabled, logViewerSelectedLevels, setLogViewerSelectedLevels, shortcuts, @@ -1184,6 +1200,7 @@ export function useSettings(): UseSettingsReturn { audioFeedbackCommand, toastDuration, checkForUpdatesOnStartup, + crashReportingEnabled, logViewerSelectedLevels, shortcuts, customAICommands, @@ -1223,6 +1240,7 @@ export function useSettings(): UseSettingsReturn { setAudioFeedbackCommand, setToastDuration, setCheckForUpdatesOnStartup, + setCrashReportingEnabled, setLogViewerSelectedLevels, setShortcuts, setCustomAICommands, diff --git a/src/renderer/main.tsx b/src/renderer/main.tsx index 1e101bcb..0e5b08d7 100644 --- a/src/renderer/main.tsx +++ b/src/renderer/main.tsx @@ -1,5 +1,6 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; +import * as Sentry from '@sentry/electron/renderer'; import MaestroConsole from './App'; import { ErrorBoundary } from './components/ErrorBoundary'; import { LayerStackProvider } from './contexts/LayerStackContext'; @@ -8,6 +9,12 @@ import { WizardProvider } from './components/Wizard'; import { logger } from './utils/logger'; import './index.css'; +// Initialize Sentry for the renderer process +// The main process handles the enabled/disabled check and initializes Sentry there +// Renderer Sentry will automatically connect to main process Sentry +// We initialize unconditionally here - if main process didn't init, this is a no-op +Sentry.init({}); + // Set up global error handlers for uncaught exceptions in renderer process window.addEventListener('error', (event: ErrorEvent) => { logger.error( diff --git a/src/renderer/utils/tabHelpers.ts b/src/renderer/utils/tabHelpers.ts index d4d4390d..f7c31253 100644 --- a/src/renderer/utils/tabHelpers.ts +++ b/src/renderer/utils/tabHelpers.ts @@ -34,7 +34,7 @@ function hasDraft(tab: AITab): boolean { * const unreadTabs = getNavigableTabs(session, true); */ export function getNavigableTabs(session: Session, showUnreadOnly = false): AITab[] { - if (!session.aiTabs || session.aiTabs.length === 0) { + if (!session || !session.aiTabs || session.aiTabs.length === 0) { return []; } @@ -54,7 +54,7 @@ export function getNavigableTabs(session: Session, showUnreadOnly = false): AITa * @returns The active AITab or undefined if no tabs exist */ export function getActiveTab(session: Session): AITab | undefined { - if (!session.aiTabs || session.aiTabs.length === 0) { + if (!session || !session.aiTabs || session.aiTabs.length === 0) { return undefined; } @@ -106,7 +106,11 @@ export interface CreateTabResult { * logs: existingLogs * }); */ -export function createTab(session: Session, options: CreateTabOptions = {}): CreateTabResult { +export function createTab(session: Session, options: CreateTabOptions = {}): CreateTabResult | null { + if (!session) { + return null; + } + const { agentSessionId = null, logs = [], @@ -170,7 +174,7 @@ export interface CloseTabResult { * } */ export function closeTab(session: Session, tabId: string): CloseTabResult | null { - if (!session.aiTabs || session.aiTabs.length === 0) { + if (!session || !session.aiTabs || session.aiTabs.length === 0) { return null; } @@ -345,8 +349,8 @@ export interface SetActiveTabResult { * } */ export function setActiveTab(session: Session, tabId: string): SetActiveTabResult | null { - // Validate that the tab exists - if (!session.aiTabs || session.aiTabs.length === 0) { + // Validate that the session and tab exists + if (!session || !session.aiTabs || session.aiTabs.length === 0) { return null; } @@ -388,7 +392,7 @@ export function setActiveTab(session: Session, tabId: string): SetActiveTabResul * } */ export function getWriteModeTab(session: Session): AITab | undefined { - if (!session.aiTabs || session.aiTabs.length === 0) { + if (!session || !session.aiTabs || session.aiTabs.length === 0) { return undefined; } @@ -416,7 +420,7 @@ export function getWriteModeTab(session: Session): AITab | undefined { * } */ export function getBusyTabs(session: Session): AITab[] { - if (!session.aiTabs || session.aiTabs.length === 0) { + if (!session || !session.aiTabs || session.aiTabs.length === 0) { return []; } @@ -439,7 +443,7 @@ export function getBusyTabs(session: Session): AITab[] { * } */ export function navigateToNextTab(session: Session, showUnreadOnly = false): SetActiveTabResult | null { - if (!session.aiTabs || session.aiTabs.length < 2) { + if (!session || !session.aiTabs || session.aiTabs.length < 2) { return null; } @@ -498,7 +502,7 @@ export function navigateToNextTab(session: Session, showUnreadOnly = false): Set * } */ export function navigateToPrevTab(session: Session, showUnreadOnly = false): SetActiveTabResult | null { - if (!session.aiTabs || session.aiTabs.length < 2) { + if (!session || !session.aiTabs || session.aiTabs.length < 2) { return null; } @@ -559,7 +563,7 @@ export function navigateToPrevTab(session: Session, showUnreadOnly = false): Set * } */ export function navigateToTabByIndex(session: Session, index: number, showUnreadOnly = false): SetActiveTabResult | null { - if (!session.aiTabs || session.aiTabs.length === 0) { + if (!session || !session.aiTabs || session.aiTabs.length === 0) { return null; }