diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2d7744e96de41b2ce51c7be4dfdfd7d2c1ec2557..1e3d71e9211e5ca3212e52bf571dccd49859d3bc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,15 @@
 -->
 
 
+## 4.1.0 (Upcoming)
+
+### ✨ Feature
+- Add features related to corrige (commentary, commit specific link / update, delete link)
+
+### 🎨 Interface
+- Ask for confirmation before creating an exercise that already exists
+
+
 ## 4.0.1 (2024-05-14)
 
 ### 🐛 Bugfix
diff --git a/NodeApp/package-lock.json b/NodeApp/package-lock.json
index 242af7df21157cbb6d1d04468bc0e287dfe681a4..69a77d024c6362a50ca1bb3b097ff62af4b7254b 100644
--- a/NodeApp/package-lock.json
+++ b/NodeApp/package-lock.json
@@ -1,24 +1,24 @@
 {
     "name": "dojo_cli",
-    "version": "4.0.1",
+    "version": "4.1.0",
     "lockfileVersion": 3,
     "requires": true,
     "packages": {
         "": {
             "name": "dojo_cli",
-            "version": "4.0.1",
+            "version": "4.1.0",
             "license": "AGPLv3",
             "dependencies": {
-                "@dotenvx/dotenvx": "^0.34.0",
-                "@eslint/js": "^9.0.0",
+                "@dotenvx/dotenvx": "^0.44.1",
+                "@eslint/js": "^9.3.0",
                 "@gitbeaker/core": "^40.0.3",
                 "@gitbeaker/requester-utils": "^40.0.3",
                 "@gitbeaker/rest": "^40.0.3",
                 "appdata-path": "^1.0.0",
-                "axios": "^1.6.8",
+                "axios": "^1.7.2",
                 "boxen": "^5.1.2",
                 "chalk": "^4.1.2",
-                "commander": "^12.0.0",
+                "commander": "^12.1.0",
                 "form-data": "^4.0.0",
                 "fs-extra": "^11.2.0",
                 "http-status-codes": "^2.3.0",
@@ -27,13 +27,13 @@
                 "jsonwebtoken": "^8.5.1",
                 "open": "^8.4.2",
                 "ora": "^5.4.1",
-                "semver": "^7.6.0",
+                "semver": "^7.6.2",
                 "tar-stream": "^3.1.7",
                 "winston": "^3.13.0",
                 "winston-transport": "^4.7.0",
-                "yaml": "^2.4.1",
-                "zod": "^3.22.5",
-                "zod-validation-error": "^3.1.0"
+                "yaml": "^2.4.2",
+                "zod": "^3.23.8",
+                "zod-validation-error": "^3.3.0"
             },
             "bin": {
                 "dojo": "dist/app.js"
@@ -42,19 +42,19 @@
                 "@types/fs-extra": "^11.0.4",
                 "@types/inquirer": "^8.2.10",
                 "@types/jsonwebtoken": "^8.5.9",
-                "@types/node": "^18.19.31",
+                "@types/node": "^18.19.33",
                 "@types/semver": "^7.5.8",
                 "@types/tar-stream": "^3.1.3",
-                "@typescript-eslint/eslint-plugin": "^7.7.0",
-                "@typescript-eslint/parser": "^7.7.0",
+                "@typescript-eslint/eslint-plugin": "^7.11.0",
+                "@typescript-eslint/parser": "^7.11.0",
                 "dotenv-vault": "^1.26.1",
                 "eslint": "^8.57.0",
                 "genversion": "^3.2.0",
                 "pkg": "^5.8.1",
                 "tiny-typed-emitter": "^2.1.0",
-                "tsx": "^4.7.2",
+                "tsx": "^4.11.0",
                 "typescript": "^5.4.5",
-                "typescript-eslint": "^7.7.0"
+                "typescript-eslint": "^7.11.0"
             }
         },
         "node_modules/@aashutoshrathi/word-wrap": {
@@ -165,17 +165,19 @@
             }
         },
         "node_modules/@dotenvx/dotenvx": {
-            "version": "0.34.0",
-            "resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-0.34.0.tgz",
-            "integrity": "sha512-0PiQUTGicI9M+pl9/GJpmzwa6E/MU0SI+K8JLTlplPIfeRv471Nd8qPBdBujCBH4kPt5maXvV5hCtdq+gV0pJw==",
+            "version": "0.44.1",
+            "resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-0.44.1.tgz",
+            "integrity": "sha512-OmOU7CRwhXydZUHeTP46GNZsGpwQ3mwrr3cUAWod+FmrKW3ib4GYe1jU++ZFyEEUNvg532QvvM7hQ44YyJrgfw==",
             "dependencies": {
                 "@inquirer/confirm": "^2.0.17",
                 "arch": "^2.1.1",
                 "chalk": "^4.1.2",
                 "commander": "^11.1.0",
                 "conf": "^10.2.0",
+                "diff": "^5.2.0",
                 "dotenv": "^16.4.5",
                 "dotenv-expand": "^11.0.6",
+                "eciesjs": "^0.4.6",
                 "execa": "^5.1.1",
                 "glob": "^10.3.10",
                 "ignore": "^5.3.0",
@@ -205,10 +207,18 @@
                 "node": ">=16"
             }
         },
+        "node_modules/@dotenvx/dotenvx/node_modules/diff": {
+            "version": "5.2.0",
+            "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz",
+            "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==",
+            "engines": {
+                "node": ">=0.3.1"
+            }
+        },
         "node_modules/@esbuild/aix-ppc64": {
-            "version": "0.19.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz",
-            "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==",
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz",
+            "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==",
             "cpu": [
                 "ppc64"
             ],
@@ -222,9 +232,9 @@
             }
         },
         "node_modules/@esbuild/android-arm": {
-            "version": "0.19.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz",
-            "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==",
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz",
+            "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==",
             "cpu": [
                 "arm"
             ],
@@ -238,9 +248,9 @@
             }
         },
         "node_modules/@esbuild/android-arm64": {
-            "version": "0.19.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz",
-            "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==",
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz",
+            "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==",
             "cpu": [
                 "arm64"
             ],
@@ -254,9 +264,9 @@
             }
         },
         "node_modules/@esbuild/android-x64": {
-            "version": "0.19.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz",
-            "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==",
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz",
+            "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==",
             "cpu": [
                 "x64"
             ],
@@ -270,9 +280,9 @@
             }
         },
         "node_modules/@esbuild/darwin-arm64": {
-            "version": "0.19.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz",
-            "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==",
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz",
+            "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==",
             "cpu": [
                 "arm64"
             ],
@@ -286,9 +296,9 @@
             }
         },
         "node_modules/@esbuild/darwin-x64": {
-            "version": "0.19.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz",
-            "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==",
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz",
+            "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==",
             "cpu": [
                 "x64"
             ],
@@ -302,9 +312,9 @@
             }
         },
         "node_modules/@esbuild/freebsd-arm64": {
-            "version": "0.19.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz",
-            "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==",
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz",
+            "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==",
             "cpu": [
                 "arm64"
             ],
@@ -318,9 +328,9 @@
             }
         },
         "node_modules/@esbuild/freebsd-x64": {
-            "version": "0.19.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz",
-            "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==",
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz",
+            "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==",
             "cpu": [
                 "x64"
             ],
@@ -334,9 +344,9 @@
             }
         },
         "node_modules/@esbuild/linux-arm": {
-            "version": "0.19.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz",
-            "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==",
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz",
+            "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==",
             "cpu": [
                 "arm"
             ],
@@ -350,9 +360,9 @@
             }
         },
         "node_modules/@esbuild/linux-arm64": {
-            "version": "0.19.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz",
-            "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==",
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz",
+            "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==",
             "cpu": [
                 "arm64"
             ],
@@ -366,9 +376,9 @@
             }
         },
         "node_modules/@esbuild/linux-ia32": {
-            "version": "0.19.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz",
-            "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==",
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz",
+            "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==",
             "cpu": [
                 "ia32"
             ],
@@ -382,9 +392,9 @@
             }
         },
         "node_modules/@esbuild/linux-loong64": {
-            "version": "0.19.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz",
-            "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==",
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz",
+            "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==",
             "cpu": [
                 "loong64"
             ],
@@ -398,9 +408,9 @@
             }
         },
         "node_modules/@esbuild/linux-mips64el": {
-            "version": "0.19.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz",
-            "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==",
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz",
+            "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==",
             "cpu": [
                 "mips64el"
             ],
@@ -414,9 +424,9 @@
             }
         },
         "node_modules/@esbuild/linux-ppc64": {
-            "version": "0.19.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz",
-            "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==",
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz",
+            "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==",
             "cpu": [
                 "ppc64"
             ],
@@ -430,9 +440,9 @@
             }
         },
         "node_modules/@esbuild/linux-riscv64": {
-            "version": "0.19.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz",
-            "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==",
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz",
+            "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==",
             "cpu": [
                 "riscv64"
             ],
@@ -446,9 +456,9 @@
             }
         },
         "node_modules/@esbuild/linux-s390x": {
-            "version": "0.19.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz",
-            "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==",
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz",
+            "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==",
             "cpu": [
                 "s390x"
             ],
@@ -462,9 +472,9 @@
             }
         },
         "node_modules/@esbuild/linux-x64": {
-            "version": "0.19.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz",
-            "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==",
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz",
+            "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==",
             "cpu": [
                 "x64"
             ],
@@ -478,9 +488,9 @@
             }
         },
         "node_modules/@esbuild/netbsd-x64": {
-            "version": "0.19.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz",
-            "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==",
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz",
+            "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==",
             "cpu": [
                 "x64"
             ],
@@ -494,9 +504,9 @@
             }
         },
         "node_modules/@esbuild/openbsd-x64": {
-            "version": "0.19.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz",
-            "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==",
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz",
+            "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==",
             "cpu": [
                 "x64"
             ],
@@ -510,9 +520,9 @@
             }
         },
         "node_modules/@esbuild/sunos-x64": {
-            "version": "0.19.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz",
-            "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==",
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz",
+            "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==",
             "cpu": [
                 "x64"
             ],
@@ -526,9 +536,9 @@
             }
         },
         "node_modules/@esbuild/win32-arm64": {
-            "version": "0.19.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz",
-            "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==",
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz",
+            "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==",
             "cpu": [
                 "arm64"
             ],
@@ -542,9 +552,9 @@
             }
         },
         "node_modules/@esbuild/win32-ia32": {
-            "version": "0.19.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz",
-            "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==",
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz",
+            "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==",
             "cpu": [
                 "ia32"
             ],
@@ -558,9 +568,9 @@
             }
         },
         "node_modules/@esbuild/win32-x64": {
-            "version": "0.19.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz",
-            "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==",
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz",
+            "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==",
             "cpu": [
                 "x64"
             ],
@@ -683,9 +693,9 @@
             }
         },
         "node_modules/@eslint/js": {
-            "version": "9.0.0",
-            "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.0.0.tgz",
-            "integrity": "sha512-RThY/MnKrhubF6+s1JflwUjPEsnCEmYCWwqa/aRISKWNXGZ9epUwft4bUMM35SdKF9xvBrLydAM1RDHd1Z//ZQ==",
+            "version": "9.3.0",
+            "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.3.0.tgz",
+            "integrity": "sha512-niBqk8iwv96+yuTwjM6bWg8ovzAPF9qkICsGtcoa5/dmqcEMfdwNAX7+/OHcJHc7wj7XqPxH98oAHytFYlw6Sw==",
             "engines": {
                 "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
             }
@@ -982,6 +992,36 @@
                 "@jridgewell/sourcemap-codec": "^1.4.14"
             }
         },
+        "node_modules/@noble/ciphers": {
+            "version": "0.4.1",
+            "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.4.1.tgz",
+            "integrity": "sha512-QCOA9cgf3Rc33owG0AYBB9wszz+Ul2kramWN8tXG44Gyciud/tbkEqvxRF/IpqQaBpRBNi9f4jdNxqB2CQCIXg==",
+            "funding": {
+                "url": "https://paulmillr.com/funding/"
+            }
+        },
+        "node_modules/@noble/curves": {
+            "version": "1.4.0",
+            "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.0.tgz",
+            "integrity": "sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==",
+            "dependencies": {
+                "@noble/hashes": "1.4.0"
+            },
+            "funding": {
+                "url": "https://paulmillr.com/funding/"
+            }
+        },
+        "node_modules/@noble/hashes": {
+            "version": "1.4.0",
+            "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz",
+            "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==",
+            "engines": {
+                "node": ">= 16"
+            },
+            "funding": {
+                "url": "https://paulmillr.com/funding/"
+            }
+        },
         "node_modules/@nodelib/fs.scandir": {
             "version": "2.1.5",
             "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -1546,12 +1586,6 @@
                 "rxjs": "^7.2.0"
             }
         },
-        "node_modules/@types/json-schema": {
-            "version": "7.0.15",
-            "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
-            "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
-            "dev": true
-        },
         "node_modules/@types/jsonfile": {
             "version": "6.1.4",
             "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz",
@@ -1579,9 +1613,9 @@
             }
         },
         "node_modules/@types/node": {
-            "version": "18.19.31",
-            "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.31.tgz",
-            "integrity": "sha512-ArgCD39YpyyrtFKIqMDvjz79jto5fcI/SVUs2HwB+f0dAzq68yqOdyaSivLiLugSziTpNXLQrVb7RZFmdZzbhA==",
+            "version": "18.19.33",
+            "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.33.tgz",
+            "integrity": "sha512-NR9+KrpSajr2qBVp/Yt5TU/rp+b5Mayi3+OlMlcg2cVCfRmcG5PWZ7S4+MG9PZ5gWBoc9Pd0BKSRViuBCRPu0A==",
             "dependencies": {
                 "undici-types": "~5.26.4"
             }
@@ -1621,21 +1655,19 @@
             "integrity": "sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g=="
         },
         "node_modules/@typescript-eslint/eslint-plugin": {
-            "version": "7.7.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.7.0.tgz",
-            "integrity": "sha512-GJWR0YnfrKnsRoluVO3PRb9r5aMZriiMMM/RHj5nnTrBy1/wIgk76XCtCKcnXGjpZQJQRFtGV9/0JJ6n30uwpQ==",
+            "version": "7.11.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.11.0.tgz",
+            "integrity": "sha512-P+qEahbgeHW4JQ/87FuItjBj8O3MYv5gELDzr8QaQ7fsll1gSMTYb6j87MYyxwf3DtD7uGFB9ShwgmCJB5KmaQ==",
             "dev": true,
             "dependencies": {
                 "@eslint-community/regexpp": "^4.10.0",
-                "@typescript-eslint/scope-manager": "7.7.0",
-                "@typescript-eslint/type-utils": "7.7.0",
-                "@typescript-eslint/utils": "7.7.0",
-                "@typescript-eslint/visitor-keys": "7.7.0",
-                "debug": "^4.3.4",
+                "@typescript-eslint/scope-manager": "7.11.0",
+                "@typescript-eslint/type-utils": "7.11.0",
+                "@typescript-eslint/utils": "7.11.0",
+                "@typescript-eslint/visitor-keys": "7.11.0",
                 "graphemer": "^1.4.0",
                 "ignore": "^5.3.1",
                 "natural-compare": "^1.4.0",
-                "semver": "^7.6.0",
                 "ts-api-utils": "^1.3.0"
             },
             "engines": {
@@ -1656,15 +1688,15 @@
             }
         },
         "node_modules/@typescript-eslint/parser": {
-            "version": "7.7.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.7.0.tgz",
-            "integrity": "sha512-fNcDm3wSwVM8QYL4HKVBggdIPAy9Q41vcvC/GtDobw3c4ndVT3K6cqudUmjHPw8EAp4ufax0o58/xvWaP2FmTg==",
+            "version": "7.11.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.11.0.tgz",
+            "integrity": "sha512-yimw99teuaXVWsBcPO1Ais02kwJ1jmNA1KxE7ng0aT7ndr1pT1wqj0OJnsYVGKKlc4QJai86l/025L6z8CljOg==",
             "dev": true,
             "dependencies": {
-                "@typescript-eslint/scope-manager": "7.7.0",
-                "@typescript-eslint/types": "7.7.0",
-                "@typescript-eslint/typescript-estree": "7.7.0",
-                "@typescript-eslint/visitor-keys": "7.7.0",
+                "@typescript-eslint/scope-manager": "7.11.0",
+                "@typescript-eslint/types": "7.11.0",
+                "@typescript-eslint/typescript-estree": "7.11.0",
+                "@typescript-eslint/visitor-keys": "7.11.0",
                 "debug": "^4.3.4"
             },
             "engines": {
@@ -1684,13 +1716,13 @@
             }
         },
         "node_modules/@typescript-eslint/scope-manager": {
-            "version": "7.7.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.7.0.tgz",
-            "integrity": "sha512-/8INDn0YLInbe9Wt7dK4cXLDYp0fNHP5xKLHvZl3mOT5X17rK/YShXaiNmorl+/U4VKCVIjJnx4Ri5b0y+HClw==",
+            "version": "7.11.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.11.0.tgz",
+            "integrity": "sha512-27tGdVEiutD4POirLZX4YzT180vevUURJl4wJGmm6TrQoiYwuxTIY98PBp6L2oN+JQxzE0URvYlzJaBHIekXAw==",
             "dev": true,
             "dependencies": {
-                "@typescript-eslint/types": "7.7.0",
-                "@typescript-eslint/visitor-keys": "7.7.0"
+                "@typescript-eslint/types": "7.11.0",
+                "@typescript-eslint/visitor-keys": "7.11.0"
             },
             "engines": {
                 "node": "^18.18.0 || >=20.0.0"
@@ -1701,13 +1733,13 @@
             }
         },
         "node_modules/@typescript-eslint/type-utils": {
-            "version": "7.7.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.7.0.tgz",
-            "integrity": "sha512-bOp3ejoRYrhAlnT/bozNQi3nio9tIgv3U5C0mVDdZC7cpcQEDZXvq8inrHYghLVwuNABRqrMW5tzAv88Vy77Sg==",
+            "version": "7.11.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.11.0.tgz",
+            "integrity": "sha512-WmppUEgYy+y1NTseNMJ6mCFxt03/7jTOy08bcg7bxJJdsM4nuhnchyBbE8vryveaJUf62noH7LodPSo5Z0WUCg==",
             "dev": true,
             "dependencies": {
-                "@typescript-eslint/typescript-estree": "7.7.0",
-                "@typescript-eslint/utils": "7.7.0",
+                "@typescript-eslint/typescript-estree": "7.11.0",
+                "@typescript-eslint/utils": "7.11.0",
                 "debug": "^4.3.4",
                 "ts-api-utils": "^1.3.0"
             },
@@ -1728,9 +1760,9 @@
             }
         },
         "node_modules/@typescript-eslint/types": {
-            "version": "7.7.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.0.tgz",
-            "integrity": "sha512-G01YPZ1Bd2hn+KPpIbrAhEWOn5lQBrjxkzHkWvP6NucMXFtfXoevK82hzQdpfuQYuhkvFDeQYbzXCjR1z9Z03w==",
+            "version": "7.11.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.11.0.tgz",
+            "integrity": "sha512-MPEsDRZTyCiXkD4vd3zywDCifi7tatc4K37KqTprCvaXptP7Xlpdw0NR2hRJTetG5TxbWDB79Ys4kLmHliEo/w==",
             "dev": true,
             "engines": {
                 "node": "^18.18.0 || >=20.0.0"
@@ -1741,13 +1773,13 @@
             }
         },
         "node_modules/@typescript-eslint/typescript-estree": {
-            "version": "7.7.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.0.tgz",
-            "integrity": "sha512-8p71HQPE6CbxIBy2kWHqM1KGrC07pk6RJn40n0DSc6bMOBBREZxSDJ+BmRzc8B5OdaMh1ty3mkuWRg4sCFiDQQ==",
+            "version": "7.11.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.11.0.tgz",
+            "integrity": "sha512-cxkhZ2C/iyi3/6U9EPc5y+a6csqHItndvN/CzbNXTNrsC3/ASoYQZEt9uMaEp+xFNjasqQyszp5TumAVKKvJeQ==",
             "dev": true,
             "dependencies": {
-                "@typescript-eslint/types": "7.7.0",
-                "@typescript-eslint/visitor-keys": "7.7.0",
+                "@typescript-eslint/types": "7.11.0",
+                "@typescript-eslint/visitor-keys": "7.11.0",
                 "debug": "^4.3.4",
                 "globby": "^11.1.0",
                 "is-glob": "^4.0.3",
@@ -1769,18 +1801,15 @@
             }
         },
         "node_modules/@typescript-eslint/utils": {
-            "version": "7.7.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.7.0.tgz",
-            "integrity": "sha512-LKGAXMPQs8U/zMRFXDZOzmMKgFv3COlxUQ+2NMPhbqgVm6R1w+nU1i4836Pmxu9jZAuIeyySNrN/6Rc657ggig==",
+            "version": "7.11.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.11.0.tgz",
+            "integrity": "sha512-xlAWwPleNRHwF37AhrZurOxA1wyXowW4PqVXZVUNCLjB48CqdPJoJWkrpH2nij9Q3Lb7rtWindtoXwxjxlKKCA==",
             "dev": true,
             "dependencies": {
                 "@eslint-community/eslint-utils": "^4.4.0",
-                "@types/json-schema": "^7.0.15",
-                "@types/semver": "^7.5.8",
-                "@typescript-eslint/scope-manager": "7.7.0",
-                "@typescript-eslint/types": "7.7.0",
-                "@typescript-eslint/typescript-estree": "7.7.0",
-                "semver": "^7.6.0"
+                "@typescript-eslint/scope-manager": "7.11.0",
+                "@typescript-eslint/types": "7.11.0",
+                "@typescript-eslint/typescript-estree": "7.11.0"
             },
             "engines": {
                 "node": "^18.18.0 || >=20.0.0"
@@ -1794,12 +1823,12 @@
             }
         },
         "node_modules/@typescript-eslint/visitor-keys": {
-            "version": "7.7.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.0.tgz",
-            "integrity": "sha512-h0WHOj8MhdhY8YWkzIF30R379y0NqyOHExI9N9KCzvmu05EgG4FumeYa3ccfKUSphyWkWQE1ybVrgz/Pbam6YA==",
+            "version": "7.11.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.11.0.tgz",
+            "integrity": "sha512-7syYk4MzjxTEk0g/w3iqtgxnFQspDJfn6QKD36xMuuhTzjcxY7F8EmBLnALjVyaOF1/bVocu3bS/2/F7rXrveQ==",
             "dev": true,
             "dependencies": {
-                "@typescript-eslint/types": "7.7.0",
+                "@typescript-eslint/types": "7.11.0",
                 "eslint-visitor-keys": "^3.4.3"
             },
             "engines": {
@@ -2024,9 +2053,9 @@
             }
         },
         "node_modules/axios": {
-            "version": "1.6.8",
-            "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz",
-            "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==",
+            "version": "1.7.2",
+            "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz",
+            "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
             "dependencies": {
                 "follow-redirects": "^1.15.6",
                 "form-data": "^4.0.0",
@@ -2432,9 +2461,9 @@
             }
         },
         "node_modules/commander": {
-            "version": "12.0.0",
-            "resolved": "https://registry.npmjs.org/commander/-/commander-12.0.0.tgz",
-            "integrity": "sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==",
+            "version": "12.1.0",
+            "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
+            "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
             "engines": {
                 "node": ">=18"
             }
@@ -2746,6 +2775,19 @@
                 "safe-buffer": "^5.0.1"
             }
         },
+        "node_modules/eciesjs": {
+            "version": "0.4.6",
+            "resolved": "https://registry.npmjs.org/eciesjs/-/eciesjs-0.4.6.tgz",
+            "integrity": "sha512-t0qLzGVKeATAA6X19hIeToxBVG8yvn/be/4XyJvTCBD53m2CK22cgzk+WW+pNYjEw5FGWZLNFoJte8lyZS/A/w==",
+            "dependencies": {
+                "@noble/ciphers": "^0.4.0",
+                "@noble/curves": "^1.2.0",
+                "@noble/hashes": "^1.3.2"
+            },
+            "engines": {
+                "node": ">=16.0.0"
+            }
+        },
         "node_modules/ejs": {
             "version": "3.1.10",
             "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
@@ -2817,9 +2859,9 @@
             }
         },
         "node_modules/esbuild": {
-            "version": "0.19.12",
-            "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz",
-            "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==",
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz",
+            "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==",
             "dev": true,
             "hasInstallScript": true,
             "bin": {
@@ -2829,29 +2871,29 @@
                 "node": ">=12"
             },
             "optionalDependencies": {
-                "@esbuild/aix-ppc64": "0.19.12",
-                "@esbuild/android-arm": "0.19.12",
-                "@esbuild/android-arm64": "0.19.12",
-                "@esbuild/android-x64": "0.19.12",
-                "@esbuild/darwin-arm64": "0.19.12",
-                "@esbuild/darwin-x64": "0.19.12",
-                "@esbuild/freebsd-arm64": "0.19.12",
-                "@esbuild/freebsd-x64": "0.19.12",
-                "@esbuild/linux-arm": "0.19.12",
-                "@esbuild/linux-arm64": "0.19.12",
-                "@esbuild/linux-ia32": "0.19.12",
-                "@esbuild/linux-loong64": "0.19.12",
-                "@esbuild/linux-mips64el": "0.19.12",
-                "@esbuild/linux-ppc64": "0.19.12",
-                "@esbuild/linux-riscv64": "0.19.12",
-                "@esbuild/linux-s390x": "0.19.12",
-                "@esbuild/linux-x64": "0.19.12",
-                "@esbuild/netbsd-x64": "0.19.12",
-                "@esbuild/openbsd-x64": "0.19.12",
-                "@esbuild/sunos-x64": "0.19.12",
-                "@esbuild/win32-arm64": "0.19.12",
-                "@esbuild/win32-ia32": "0.19.12",
-                "@esbuild/win32-x64": "0.19.12"
+                "@esbuild/aix-ppc64": "0.20.2",
+                "@esbuild/android-arm": "0.20.2",
+                "@esbuild/android-arm64": "0.20.2",
+                "@esbuild/android-x64": "0.20.2",
+                "@esbuild/darwin-arm64": "0.20.2",
+                "@esbuild/darwin-x64": "0.20.2",
+                "@esbuild/freebsd-arm64": "0.20.2",
+                "@esbuild/freebsd-x64": "0.20.2",
+                "@esbuild/linux-arm": "0.20.2",
+                "@esbuild/linux-arm64": "0.20.2",
+                "@esbuild/linux-ia32": "0.20.2",
+                "@esbuild/linux-loong64": "0.20.2",
+                "@esbuild/linux-mips64el": "0.20.2",
+                "@esbuild/linux-ppc64": "0.20.2",
+                "@esbuild/linux-riscv64": "0.20.2",
+                "@esbuild/linux-s390x": "0.20.2",
+                "@esbuild/linux-x64": "0.20.2",
+                "@esbuild/netbsd-x64": "0.20.2",
+                "@esbuild/openbsd-x64": "0.20.2",
+                "@esbuild/sunos-x64": "0.20.2",
+                "@esbuild/win32-arm64": "0.20.2",
+                "@esbuild/win32-ia32": "0.20.2",
+                "@esbuild/win32-x64": "0.20.2"
             }
         },
         "node_modules/escalade": {
@@ -3560,9 +3602,9 @@
             }
         },
         "node_modules/get-tsconfig": {
-            "version": "4.7.3",
-            "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz",
-            "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==",
+            "version": "4.7.5",
+            "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz",
+            "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==",
             "dev": true,
             "dependencies": {
                 "resolve-pkg-maps": "^1.0.0"
@@ -5493,12 +5535,9 @@
             "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
         },
         "node_modules/semver": {
-            "version": "7.6.0",
-            "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
-            "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
-            "dependencies": {
-                "lru-cache": "^6.0.0"
-            },
+            "version": "7.6.2",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
+            "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
             "bin": {
                 "semver": "bin/semver.js"
             },
@@ -5506,17 +5545,6 @@
                 "node": ">=10"
             }
         },
-        "node_modules/semver/node_modules/lru-cache": {
-            "version": "6.0.0",
-            "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
-            "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
-            "dependencies": {
-                "yallist": "^4.0.0"
-            },
-            "engines": {
-                "node": ">=10"
-            }
-        },
         "node_modules/set-function-length": {
             "version": "1.2.2",
             "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
@@ -6010,13 +6038,13 @@
             "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
         },
         "node_modules/tsx": {
-            "version": "4.7.2",
-            "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.2.tgz",
-            "integrity": "sha512-BCNd4kz6fz12fyrgCTEdZHGJ9fWTGeUzXmQysh0RVocDY3h4frk05ZNCXSy4kIenF7y/QnrdiVpTsyNRn6vlAw==",
+            "version": "4.11.0",
+            "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.11.0.tgz",
+            "integrity": "sha512-vzGGELOgAupsNVssAmZjbUDfdm/pWP4R+Kg8TVdsonxbXk0bEpE1qh0yV6/QxUVXaVlNemgcPajGdJJ82n3stg==",
             "dev": true,
             "dependencies": {
-                "esbuild": "~0.19.10",
-                "get-tsconfig": "^4.7.2"
+                "esbuild": "~0.20.2",
+                "get-tsconfig": "^4.7.5"
             },
             "bin": {
                 "tsx": "dist/cli.mjs"
@@ -6077,14 +6105,14 @@
             }
         },
         "node_modules/typescript-eslint": {
-            "version": "7.7.0",
-            "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.7.0.tgz",
-            "integrity": "sha512-wZZ+7mTQJCn4mGAvzdERtL4vwKGM/mF9cMSMeKUllz3Hgbd1Mdd5L60Q+nJmCio9RB4OyMMr0EX4Ry2Q7jiAyw==",
+            "version": "7.11.0",
+            "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.11.0.tgz",
+            "integrity": "sha512-ZKe3yHF/IS/kCUE4CGE3UgtK+Q7yRk1e9kwEI0rqm9XxMTd9P1eHe0LVVtrZ3oFuIQ2unJ9Xn0vTsLApzJ3aPw==",
             "dev": true,
             "dependencies": {
-                "@typescript-eslint/eslint-plugin": "7.7.0",
-                "@typescript-eslint/parser": "7.7.0",
-                "@typescript-eslint/utils": "7.7.0"
+                "@typescript-eslint/eslint-plugin": "7.11.0",
+                "@typescript-eslint/parser": "7.11.0",
+                "@typescript-eslint/utils": "7.11.0"
             },
             "engines": {
                 "node": "^18.18.0 || >=20.0.0"
@@ -6292,15 +6320,10 @@
                 "node": ">=10"
             }
         },
-        "node_modules/yallist": {
-            "version": "4.0.0",
-            "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
-            "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
-        },
         "node_modules/yaml": {
-            "version": "2.4.1",
-            "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz",
-            "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==",
+            "version": "2.4.2",
+            "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.2.tgz",
+            "integrity": "sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==",
             "bin": {
                 "yaml": "bin.mjs"
             },
@@ -6357,17 +6380,17 @@
             }
         },
         "node_modules/zod": {
-            "version": "3.22.5",
-            "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.5.tgz",
-            "integrity": "sha512-HqnGsCdVZ2xc0qWPLdO25WnseXThh0kEYKIdV5F/hTHO75hNZFp8thxSeHhiPrHZKrFTo1SOgkAj9po5bexZlw==",
+            "version": "3.23.8",
+            "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz",
+            "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==",
             "funding": {
                 "url": "https://github.com/sponsors/colinhacks"
             }
         },
         "node_modules/zod-validation-error": {
-            "version": "3.1.0",
-            "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-3.1.0.tgz",
-            "integrity": "sha512-zujS6HqJjMZCsvjfbnRs7WI3PXN39ovTcY1n8a+KTm4kOH0ZXYsNiJkH1odZf4xZKMkBDL7M2rmQ913FCS1p9w==",
+            "version": "3.3.0",
+            "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-3.3.0.tgz",
+            "integrity": "sha512-Syib9oumw1NTqEv4LT0e6U83Td9aVRk9iTXPUQr1otyV1PuXQKOvOwhMNqZIq5hluzHP2pMgnOmHEo7kPdI2mw==",
             "engines": {
                 "node": ">=18.0.0"
             },
diff --git a/NodeApp/package.json b/NodeApp/package.json
index 9bac46241c13d06b253e72f47b9ecb39e24a6ad1..ecaf98a4e6a1feddf331a0fc722ef974976b54e6 100644
--- a/NodeApp/package.json
+++ b/NodeApp/package.json
@@ -1,7 +1,7 @@
 {
     "name"           : "dojo_cli",
     "description"    : "CLI of the Dojo project",
-    "version"        : "4.0.1",
+    "version"        : "4.1.0",
     "license"        : "AGPLv3",
     "author"         : "Michaël Minelli <dojo@minelli.me>",
     "main"           : "dist/app.js",
@@ -33,16 +33,16 @@
         "test"        : "echo \"Error: no test specified\" && exit 1"
     },
     "dependencies"   : {
-        "@dotenvx/dotenvx"          : "^0.34.0",
-        "@eslint/js"                : "^9.0.0",
+        "@dotenvx/dotenvx"          : "^0.44.1",
+        "@eslint/js"                : "^9.3.0",
         "@gitbeaker/core"           : "^40.0.3",
         "@gitbeaker/requester-utils": "^40.0.3",
         "@gitbeaker/rest"           : "^40.0.3",
         "appdata-path"              : "^1.0.0",
-        "axios"                     : "^1.6.8",
+        "axios"                     : "^1.7.2",
         "boxen"                     : "^5.1.2",
         "chalk"                     : "^4.1.2",
-        "commander"                 : "^12.0.0",
+        "commander"                 : "^12.1.0",
         "form-data"                 : "^4.0.0",
         "fs-extra"                  : "^11.2.0",
         "http-status-codes"         : "^2.3.0",
@@ -51,30 +51,30 @@
         "jsonwebtoken"              : "^8.5.1",
         "open"                      : "^8.4.2",
         "ora"                       : "^5.4.1",
-        "semver"                    : "^7.6.0",
+        "semver"                    : "^7.6.2",
         "tar-stream"                : "^3.1.7",
         "winston"                   : "^3.13.0",
         "winston-transport"         : "^4.7.0",
-        "yaml"                      : "^2.4.1",
-        "zod"                       : "^3.22.5",
-        "zod-validation-error"      : "^3.1.0"
+        "yaml"                      : "^2.4.2",
+        "zod"                       : "^3.23.8",
+        "zod-validation-error"      : "^3.3.0"
     },
     "devDependencies": {
         "@types/fs-extra"                 : "^11.0.4",
         "@types/inquirer"                 : "^8.2.10",
         "@types/jsonwebtoken"             : "^8.5.9",
-        "@types/node"                     : "^18.19.31",
+        "@types/node"                     : "^18.19.33",
         "@types/semver"                   : "^7.5.8",
         "@types/tar-stream"               : "^3.1.3",
-        "@typescript-eslint/eslint-plugin": "^7.7.0",
-        "@typescript-eslint/parser"       : "^7.7.0",
+        "@typescript-eslint/eslint-plugin": "^7.11.0",
+        "@typescript-eslint/parser"       : "^7.11.0",
         "dotenv-vault"                    : "^1.26.1",
         "eslint"                          : "^8.57.0",
         "genversion"                      : "^3.2.0",
         "pkg"                             : "^5.8.1",
         "tiny-typed-emitter"              : "^2.1.0",
-        "tsx"                             : "^4.7.2",
+        "tsx"                             : "^4.11.0",
         "typescript"                      : "^5.4.5",
-        "typescript-eslint"               : "^7.7.0"
+        "typescript-eslint"               : "^7.11.0"
     }
 }
diff --git a/NodeApp/src/commander/assignment/subcommands/correction/AssignmentCorrectionCommand.ts b/NodeApp/src/commander/assignment/subcommands/correction/AssignmentCorrectionCommand.ts
index 1ff39af42304fd623e842705375f9b445f1c2461..3eb929a078f49994e94e544dd6f381741da578f5 100644
--- a/NodeApp/src/commander/assignment/subcommands/correction/AssignmentCorrectionCommand.ts
+++ b/NodeApp/src/commander/assignment/subcommands/correction/AssignmentCorrectionCommand.ts
@@ -1,6 +1,7 @@
 import CommanderCommand                  from '../../../CommanderCommand.js';
 import AssignmentCorrectionLinkCommand   from './subcommands/AssignmentCorrectionLinkCommand.js';
 import AssignmentCorrectionUpdateCommand from './subcommands/AssignmentCorrectionUpdateCommand.js';
+import AssignmentCorrectionUnlinkCommand from './subcommands/AssignmentCorrectionUnlinkCommand.js';
 
 
 class AssignmentCorrectionCommand extends CommanderCommand {
@@ -14,6 +15,7 @@ class AssignmentCorrectionCommand extends CommanderCommand {
     protected defineSubCommands() {
         AssignmentCorrectionLinkCommand.registerOnCommand(this.command);
         AssignmentCorrectionUpdateCommand.registerOnCommand(this.command);
+        AssignmentCorrectionUnlinkCommand.registerOnCommand(this.command);
     }
 
     protected async commandAction(): Promise<void> {
diff --git a/NodeApp/src/commander/assignment/subcommands/correction/subcommands/AssignmentCorrectionLinkUpdateCommand.ts b/NodeApp/src/commander/assignment/subcommands/correction/subcommands/AssignmentCorrectionLinkUpdateCommand.ts
index 230e0202ee9f69357574658b9a3b4a21a00297ca..30c3f40f87f7eaf3af4c92ab556e3bfe2d8e65f1 100644
--- a/NodeApp/src/commander/assignment/subcommands/correction/subcommands/AssignmentCorrectionLinkUpdateCommand.ts
+++ b/NodeApp/src/commander/assignment/subcommands/correction/subcommands/AssignmentCorrectionLinkUpdateCommand.ts
@@ -1,9 +1,9 @@
 import CommanderCommand   from '../../../../CommanderCommand.js';
 import ora                from 'ora';
 import DojoBackendManager from '../../../../../managers/DojoBackendManager.js';
-import SessionManager     from '../../../../../managers/SessionManager.js';
 import Assignment         from '../../../../../sharedByClients/models/Assignment.js';
 import TextStyle          from '../../../../../types/TextStyle.js';
+import GlobalHelper       from '../../../../../helpers/GlobalHelper.js';
 
 
 abstract class AssignmentCorrectionLinkUpdateCommand extends CommanderCommand {
@@ -14,31 +14,28 @@ abstract class AssignmentCorrectionLinkUpdateCommand extends CommanderCommand {
             .description(this.isUpdate ? 'update a correction of an assignment' : 'link an exercise repo as a correction for an assignment')
             .argument('<string>', 'id or url of the exercise that is the correction')
             .requiredOption('-a, --assignment <string>', 'id or url of the assignment of the correction')
+            .option('-c, --commit <string>', 'specific commit to link as correction (default: last commit)')
+            .option('-d, --description <string>', 'description of the correction (limited to 80 characters, default: empty)')
             .action(this.commandAction.bind(this));
     }
 
-    protected async commandAction(exerciseIdOrUrl: string, options: { assignment: string }): Promise<void> {
+    protected async commandAction(exerciseIdOrUrl: string, options: { assignment: string, commit?: string, description?: string }): Promise<void> {
         let assignment!: Assignment | undefined;
 
-        // Check access
+        // Check requirements
         {
-            console.log(TextStyle.BLOCK('Please wait while we check access...'));
-
-            const assignmentGetSpinner: ora.Ora = ora('Checking if assignment exists').start();
-            assignment = await DojoBackendManager.getAssignment(options.assignment);
-            if ( !assignment ) {
-                assignmentGetSpinner.fail(`The assignment doesn't exists`);
+            if ( options.description && options.description.length > 80 ) {
+                ora('Description is limited to 80 characters').start().fail();
                 return;
             }
-            assignmentGetSpinner.succeed(`The assignment exists`);
-
+        }
 
-            const assignmentAccessSpinner: ora.Ora = ora('Checking assignment access').start();
-            if ( assignment.staff.find(staff => staff.id === SessionManager.profile?.id) === undefined ) {
-                assignmentAccessSpinner.fail(`You are not in the staff of the assignment`);
+        // Check access
+        {
+            assignment = await GlobalHelper.checkAssignmentCorrectionAccess(options.assignment);
+            if ( !assignment ) {
                 return;
             }
-            assignmentAccessSpinner.succeed(`You are in the staff of the assignment`);
 
 
             const assignmentPublishedSpinner: ora.Ora = ora('Checking assignment').start();
@@ -53,7 +50,7 @@ abstract class AssignmentCorrectionLinkUpdateCommand extends CommanderCommand {
         {
             console.log(TextStyle.BLOCK('Please wait while we link the exercise...'));
 
-            await DojoBackendManager.linkUpdateCorrection(exerciseIdOrUrl, assignment, this.isUpdate);
+            await DojoBackendManager.linkUpdateCorrection(exerciseIdOrUrl, assignment, options.commit, options.description, this.isUpdate);
         }
     }
 }
diff --git a/NodeApp/src/commander/assignment/subcommands/correction/subcommands/AssignmentCorrectionUnlinkCommand.ts b/NodeApp/src/commander/assignment/subcommands/correction/subcommands/AssignmentCorrectionUnlinkCommand.ts
new file mode 100644
index 0000000000000000000000000000000000000000..78cf1cbba971cf21ce17c0af8c03e30e66a9346c
--- /dev/null
+++ b/NodeApp/src/commander/assignment/subcommands/correction/subcommands/AssignmentCorrectionUnlinkCommand.ts
@@ -0,0 +1,40 @@
+import Assignment         from '../../../../../sharedByClients/models/Assignment.js';
+import TextStyle          from '../../../../../types/TextStyle.js';
+import DojoBackendManager from '../../../../../managers/DojoBackendManager.js';
+import CommanderCommand   from '../../../../CommanderCommand.js';
+import GlobalHelper       from '../../../../../helpers/GlobalHelper.js';
+
+
+class AssignmentCorrectionLinkCommand extends CommanderCommand {
+    protected commandName: string = 'unlink';
+
+    protected defineCommand() {
+        this.command
+            .description('remove a correction of an assignment')
+            .argument('<string>', 'id or url of the exercise that is the correction')
+            .requiredOption('-a, --assignment <string>', 'id or url of the assignment of the correction')
+            .action(this.commandAction.bind(this));
+    }
+
+    protected async commandAction(exerciseIdOrUrl: string, options: { assignment: string }): Promise<void> {
+        let assignment!: Assignment | undefined;
+
+        // Check access
+        {
+            assignment = await GlobalHelper.checkAssignmentCorrectionAccess(options.assignment);
+            if ( !assignment ) {
+                return;
+            }
+        }
+
+        // Link the exercise
+        {
+            console.log(TextStyle.BLOCK('Please wait while we unlink the exercise...'));
+
+            await DojoBackendManager.unlinkCorrection(exerciseIdOrUrl, assignment);
+        }
+    }
+}
+
+
+export default new AssignmentCorrectionLinkCommand();
\ No newline at end of file
diff --git a/NodeApp/src/commander/exercise/subcommands/ExerciseCorrectionCommand.ts b/NodeApp/src/commander/exercise/subcommands/ExerciseCorrectionCommand.ts
index 6dfddd1a4eed2f39a8ae2def689536d4b9275bdf..0a7aac7bb2302c1b1ec538803f4e87c1fb4d567e 100644
--- a/NodeApp/src/commander/exercise/subcommands/ExerciseCorrectionCommand.ts
+++ b/NodeApp/src/commander/exercise/subcommands/ExerciseCorrectionCommand.ts
@@ -39,8 +39,10 @@ class ExerciseCorrectionCommand extends CommanderCommand {
 
     private getCorrections(assignment: Assignment): Array<CorrectionResume> {
         return assignment.corrections.map(correction => {
+            const authors = correction.name.replace(correction.assignmentName, '').split('-')[2].trim();
+
             return {
-                name : correction.name.replace(correction.assignmentName, '').split('-')[2].trim(),
+                name : (correction.correctionDescription && correction.correctionDescription !== '' ? `${ correction.correctionDescription } (${ authors })` : authors),
                 value: correction.correctionCommit?.web_url?.replace('/commit/', '/tree/') ?? ''
             };
         });
diff --git a/NodeApp/src/commander/exercise/subcommands/ExerciseCreateCommand.ts b/NodeApp/src/commander/exercise/subcommands/ExerciseCreateCommand.ts
index b82e7c597b4fc64e94f3929132db5d4b8e488c06..73a67c5387e448c4e904808e9c4341cbde33c971 100644
--- a/NodeApp/src/commander/exercise/subcommands/ExerciseCreateCommand.ts
+++ b/NodeApp/src/commander/exercise/subcommands/ExerciseCreateCommand.ts
@@ -7,6 +7,7 @@ import Exercise           from '../../../sharedByClients/models/Exercise.js';
 import * as Gitlab        from '@gitbeaker/rest';
 import TextStyle          from '../../../types/TextStyle.js';
 import GitlabManager      from '../../../managers/GitlabManager.js';
+import inquirer           from 'inquirer';
 
 
 type CommandOptions = { assignment: string, members_id?: Array<number>, members_username?: Array<string>, clone?: string | boolean }
@@ -16,7 +17,7 @@ class ExerciseCreateCommand extends CommanderCommand {
     protected commandName: string = 'create';
 
     private members!: Array<Gitlab.UserSchema> | undefined;
-    private assignment!: Assignment | undefined;
+    private assignment!: (Assignment & { myExercises?: Array<Exercise> }) | undefined;
     private exercise!: Exercise;
 
     protected defineCommand() {
@@ -46,7 +47,7 @@ class ExerciseCreateCommand extends CommanderCommand {
                                                       text  : 'Checking if assignment exists',
                                                       indent: 4
                                                   }).start();
-        this.assignment = await DojoBackendManager.getAssignment(options.assignment);
+        this.assignment = await DojoBackendManager.getAssignment(options.assignment, true);
         if ( !this.assignment ) {
             assignmentGetSpinner.fail(`Assignment "${ options.assignment }" doesn't exists`);
             throw new Error();
@@ -62,6 +63,36 @@ class ExerciseCreateCommand extends CommanderCommand {
             throw new Error();
         }
         assignmentPublishedSpinner.succeed(`Assignment "${ this.assignment.name }" is published`);
+
+        if ( this.assignment.myExercises && this.assignment.myExercises.length > 0 ) {
+            const oraInfo = (message: string, indent: number = 12) => {
+                ora({
+                        text  : message,
+                        indent: indent
+                    }).start().info();
+            };
+
+            oraInfo(TextStyle.WARNING(`You already created ${ this.assignment.myExercises.length } exercises for this assignment:`), 4);
+
+            for ( const exercise of this.assignment.myExercises ) {
+                oraInfo(`${ TextStyle.LIST_ITEM_NAME('Exercice Id:') } ${ exercise.id }`, 8);
+                oraInfo(`${ TextStyle.LIST_ITEM_NAME('Creation date:') } ${ exercise.gitlabCreationInfo.created_at }`);
+                oraInfo(`${ TextStyle.LIST_ITEM_NAME('Repository:') } ${ exercise.gitlabCreationInfo.web_url }`);
+                oraInfo(`${ TextStyle.LIST_ITEM_NAME('Members:') } ${ exercise.members?.map(member => member.gitlabUsername).join(', ') ?? 'There is only you' }`);
+            }
+
+            const confirm: boolean = (await inquirer.prompt({
+                                                                name   : 'confirm',
+                                                                prefix : '       ',
+                                                                message: `${ TextStyle.QUESTION('?') } You already created ${ this.assignment.myExercises.length } exercises for this assignment (see above). Are you sure you want to create a new one?`,
+                                                                type   : 'confirm',
+                                                                default: false
+                                                            })).confirm;
+
+            if ( !confirm ) {
+                throw new Error();
+            }
+        }
     }
 
     private async createExercise() {
diff --git a/NodeApp/src/helpers/GlobalHelper.ts b/NodeApp/src/helpers/GlobalHelper.ts
index d14735a8160fde93be2a725420d3532361c05872..d79317fd487a954157d4287071daaf8b345f578a 100644
--- a/NodeApp/src/helpers/GlobalHelper.ts
+++ b/NodeApp/src/helpers/GlobalHelper.ts
@@ -1,6 +1,10 @@
 import { Command, Option } from 'commander';
 import Config              from '../config/Config.js';
 import SessionManager      from '../managers/SessionManager.js';
+import TextStyle           from '../types/TextStyle.js';
+import ora                 from 'ora';
+import DojoBackendManager  from '../managers/DojoBackendManager.js';
+import Assignment          from '../sharedByClients/models/Assignment.js';
 
 
 class GlobalHelper {
@@ -20,6 +24,29 @@ class GlobalHelper {
 
         return SessionManager.gitlabCredentials.accessToken ?? '';
     };
+
+
+    public async checkAssignmentCorrectionAccess(assignmentName: string): Promise<Assignment | undefined> {
+        console.log(TextStyle.BLOCK('Please wait while we check access...'));
+
+        const assignmentGetSpinner: ora.Ora = ora('Checking if assignment exists').start();
+        const assignment = await DojoBackendManager.getAssignment(assignmentName);
+        if ( !assignment ) {
+            assignmentGetSpinner.fail(`The assignment doesn't exists`);
+            return undefined;
+        }
+        assignmentGetSpinner.succeed(`The assignment exists`);
+
+
+        const assignmentAccessSpinner: ora.Ora = ora('Checking assignment access').start();
+        if ( assignment.staff.find(staff => staff.id === SessionManager.profile?.id) === undefined ) {
+            assignmentAccessSpinner.fail(`You are not in the staff of the assignment`);
+            return undefined;
+        }
+        assignmentAccessSpinner.succeed(`You are in the staff of the assignment`);
+
+        return assignment;
+    }
 }
 
 
diff --git a/NodeApp/src/managers/DojoBackendManager.ts b/NodeApp/src/managers/DojoBackendManager.ts
index a3fd87ee0f19d1db497c58c261e9c1a665cf80b9..8c8a5a9685c1ab1fb2cabbfc4740f2914b54beae 100644
--- a/NodeApp/src/managers/DojoBackendManager.ts
+++ b/NodeApp/src/managers/DojoBackendManager.ts
@@ -93,9 +93,9 @@ class DojoBackendManager {
     }
 
 
-    public async getAssignment(nameOrUrl: string): Promise<Assignment | undefined> {
+    public async getAssignment(nameOrUrl: string, getMyExercises: boolean = false): Promise<Assignment | undefined> {
         try {
-            return (await axios.get<DojoBackendResponse<Assignment>>(DojoBackendHelper.getApiUrl(ApiRoute.ASSIGNMENT_GET, { assignmentNameOrUrl: nameOrUrl }))).data.data;
+            return (await axios.get<DojoBackendResponse<Assignment>>(DojoBackendHelper.getApiUrl(ApiRoute.ASSIGNMENT_GET, { assignmentNameOrUrl: nameOrUrl }), getMyExercises ? { params: { getMyExercises } } : {})).data.data;
         } catch ( error ) {
             return undefined;
         }
@@ -193,7 +193,7 @@ class DojoBackendManager {
         }
     }
 
-    public async linkUpdateCorrection(exerciseIdOrUrl: string, assignment: Assignment, isUpdate: boolean, verbose: boolean = true): Promise<boolean> {
+    public async linkUpdateCorrection(exerciseIdOrUrl: string, assignment: Assignment, commit: string | undefined, description: string | undefined, isUpdate: boolean, verbose: boolean = true): Promise<boolean> {
         const spinner: ora.Ora = ora(`${ isUpdate ? 'Updating' : 'Linking' } correction`);
 
         if ( verbose ) {
@@ -202,13 +202,15 @@ class DojoBackendManager {
 
         try {
             const axiosFunction = isUpdate ? axios.patch.bind(axios) : axios.post.bind(axios);
-            const route = isUpdate ? ApiRoute.ASSIGNMENT_CORRECTION_UPDATE : ApiRoute.ASSIGNMENT_CORRECTION_LINK;
+            const route = isUpdate ? ApiRoute.ASSIGNMENT_CORRECTION_UPDATE_DELETE : ApiRoute.ASSIGNMENT_CORRECTION_LINK;
 
             await axiosFunction(DojoBackendHelper.getApiUrl(route, {
                 assignmentNameOrUrl: assignment.name,
                 exerciseIdOrUrl    : exerciseIdOrUrl
             }), {
-                                    exerciseIdOrUrl: exerciseIdOrUrl
+                                    exerciseIdOrUrl: exerciseIdOrUrl,
+                                    commit         : commit,
+                                    description    : description
                                 });
 
             if ( verbose ) {
@@ -222,6 +224,31 @@ class DojoBackendManager {
             return false;
         }
     }
+
+    public async unlinkCorrection(exerciseIdOrUrl: string, assignment: Assignment, verbose: boolean = true): Promise<boolean> {
+        const spinner: ora.Ora = ora(`Unlinking correction`);
+
+        if ( verbose ) {
+            spinner.start();
+        }
+
+        try {
+            await axios.delete(DojoBackendHelper.getApiUrl(ApiRoute.ASSIGNMENT_CORRECTION_UPDATE_DELETE, {
+                assignmentNameOrUrl: assignment.name,
+                exerciseIdOrUrl    : exerciseIdOrUrl
+            }));
+
+            if ( verbose ) {
+                spinner.succeed(`Correction unlinked`);
+            }
+
+            return true;
+        } catch ( error ) {
+            this.handleApiError(error, spinner, verbose, `Correction unlink error: ${ error }`);
+
+            return false;
+        }
+    }
 }
 
 
diff --git a/NodeApp/src/sharedByClients b/NodeApp/src/sharedByClients
index 4011aa146ae4b808da599b8eb0cca2d36e82a52c..55a94e77db69635e1ca837a52de29cb04d0b4138 160000
--- a/NodeApp/src/sharedByClients
+++ b/NodeApp/src/sharedByClients
@@ -1 +1 @@
-Subproject commit 4011aa146ae4b808da599b8eb0cca2d36e82a52c
+Subproject commit 55a94e77db69635e1ca837a52de29cb04d0b4138
diff --git a/NodeApp/src/types/TextStyle.ts b/NodeApp/src/types/TextStyle.ts
index e3f82ea36ea530bd395a1282dc3100f370d5a7e3..266f1e3129c6936bb1f9ac05dbd977e555976413 100644
--- a/NodeApp/src/types/TextStyle.ts
+++ b/NodeApp/src/types/TextStyle.ts
@@ -5,6 +5,7 @@ class TextStyle {
     public readonly BLOCK = chalk.cyan;
     public readonly CODE = chalk.bgHex('F7F7F7').grey.italic;
     public readonly LIST_ITEM_NAME = chalk.magenta;
+    public readonly QUESTION = chalk.greenBright;
     public readonly URL = chalk.blue.underline;
     public readonly WARNING = chalk.red;
 }