diff --git a/LICENSE b/LICENSE
index ca4fe13006a1fcb8fa078da3d6ebbe34213cb20a..41400bc9954374f2d1e66516a87524cc555359cf 100644
--- a/LICENSE
+++ b/LICENSE
@@ -629,7 +629,7 @@ to attach them to the start of each source file to most effectively
 state the exclusion of warranty; and each file should have at least
 the "copyright" line and a pointer to where the full notice is found.
 
-    NodeSharedCode
+    NodeClientSharedCode
     Copyright (C) 2023  ISC / projects / Dojo / Projects / Shared
 
     This program is free software: you can redistribute it and/or modify
diff --git a/README.md b/README.md
index e0c65cf50afb02dc946e602fd08b2e5102f96e04..a0170e24c2a493cf92fd40f70341be88f95ef289 100644
--- a/README.md
+++ b/README.md
@@ -1,21 +1,24 @@
 # NodeSharedCode
 
-This repo contains some code that can be shared across node projects of Dojo.
+This repo contains some code that can be shared across clients projects of Dojo.
 
 ## Prerequisites
 
+These shared modules are needed :
+
+- `NodeSharedCode` imported in parent directory with directory name `shared`
+
 These packages are needed :
 
-- `json5`
-- `tar-stream`
-- `winston`
-- `zod`
-- `zod-validation-error`
+- `boxen@5.1`
+- `chalk@4.1`
+- `fs-extra`
+- `yaml`
 
 ## How to use it
 
 By adding this repo as submodule
 
 ```bash
-git submodule add ../../shared/nodesharedcode.git shared
+git submodule add ../../shared/nodeclientsharedcode.git sharedByClients
 ```
\ No newline at end of file
diff --git a/config/SharedConfig.ts b/config/SharedConfig.ts
deleted file mode 100644
index 0f8f8b0397b4a855f9a761934e7a37f5a9e6b9a3..0000000000000000000000000000000000000000
--- a/config/SharedConfig.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-class SharedConfig {
-    public readonly production: boolean;
-    public debug: boolean = false;
-
-    public readonly logsFolder: string;
-
-    public gitlab: {
-        URL: string, apiURL: string
-    };
-
-    public readonly login: {
-        gitlab: {
-            client: {
-                id: string
-            }, url: {
-                redirect: string, token: string
-            }
-        }
-    };
-
-
-    constructor() {
-        this.production = process.env.NODE_ENV === 'production';
-
-        this.logsFolder = process.env.LOGS_FOLDER || '';
-
-        this.gitlab = {
-            URL   : process.env.GITLAB_URL || '',
-            apiURL: process.env.GITLAB_API_URL || ''
-        };
-
-        this.login = {
-            gitlab: {
-                client: {
-                    id: process.env.LOGIN_GITLAB_CLIENT_ID || ''
-                },
-                url   : {
-                    redirect: process.env.LOGIN_GITLAB_URL_REDIRECT || '',
-                    token   : process.env.LOGIN_GITLAB_URL_TOKEN || ''
-                }
-            }
-        };
-    }
-}
-
-
-export default new SharedConfig();
diff --git a/helpers/ArchiveHelper.ts b/helpers/ArchiveHelper.ts
deleted file mode 100644
index f4449d6e8f4953227e0b422bb0a647a85432351c..0000000000000000000000000000000000000000
--- a/helpers/ArchiveHelper.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-import fs           from 'node:fs';
-import path         from 'node:path';
-import tar          from 'tar-stream';
-import stream       from 'node:stream';
-import { Writable } from 'stream';
-import zlib         from 'zlib';
-
-
-class ArchiveHelper {
-    private async explore(absoluteBasePath: string, rootPath: string, pack: tar.Pack) {
-        for ( let file of await fs.promises.readdir(rootPath) ) {
-            if ( file === 'output.tar' ) {
-                continue;
-            }
-            file = path.join(rootPath, file);
-            const stat = await fs.promises.stat(file);
-            if ( stat.isDirectory() ) {
-                await this.explore(absoluteBasePath, file, pack);
-                continue;
-            }
-            const entry = pack.entry({
-                                         name: file.replace(absoluteBasePath, ''),
-                                         size: stat.size
-                                     }, (err) => {
-                if ( err ) {
-                    throw err;
-                }
-            });
-            const stream = fs.createReadStream(file);
-            stream.pipe(entry);
-        }
-    }
-
-    private async compress(folderPath: string, tarDataStream: stream.Writable) {
-        const pack = tar.pack();
-
-        await this.explore(folderPath, folderPath, pack);
-
-        pack.pipe(zlib.createGzip()).pipe(tarDataStream);
-        pack.finalize();
-    }
-
-    public async getBase64(folderPath: string): Promise<string> {
-        let data: string;
-        const tarDataStream = new stream.Writable({
-                                                      write(this: Writable, chunk: Buffer, _encoding: BufferEncoding, next: (error?: Error | null) => void) {
-                                                          if ( data ) {
-                                                              data += chunk.toString('hex');
-                                                          } else {
-                                                              data = chunk.toString('hex');
-                                                          }
-                                                          next();
-                                                      }
-                                                  });
-
-        await this.compress(folderPath, tarDataStream);
-
-        data = await (new Promise((resolve) => {
-            tarDataStream.on('close', () => {
-                resolve(data);
-            });
-        }));
-
-        return Buffer.from(data, 'hex').toString('base64');
-    }
-}
-
-
-export default new ArchiveHelper();
\ No newline at end of file
diff --git a/helpers/Dojo/SharedAssignmentHelper.ts b/helpers/Dojo/SharedAssignmentHelper.ts
deleted file mode 100644
index b103f8cc526ed60a9aa6b7c5276557bcf1ab6635..0000000000000000000000000000000000000000
--- a/helpers/Dojo/SharedAssignmentHelper.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import AssignmentFile       from '../../types/Dojo/AssignmentFile';
-import GitlabPipelineStatus from '../../types/Gitlab/GitlabPipelineStatus';
-import DojoStatusCode       from '../../types/Dojo/DojoStatusCode';
-import GitlabPipeline       from '../../types/Gitlab/GitlabPipeline';
-import SharedGitlabManager  from '../../managers/SharedGitlabManager';
-import Json5FileValidator   from '../Json5FileValidator';
-
-
-class SharedAssignmentHelper {
-    validateDescriptionFile(filePathOrStr: string, isFile: boolean = true, version: number = 1): { content: AssignmentFile | undefined, isValid: boolean, error: string | null } {
-        switch ( version ) {
-            case 1:
-                return Json5FileValidator.validateFile(AssignmentFile, filePathOrStr, isFile);
-            default:
-                return {
-                    content: undefined,
-                    isValid: false,
-                    error  : `Version ${ version } not supported`
-                };
-        }
-    }
-
-    async isPublishable(repositoryId: number): Promise<{ isPublishable: boolean, lastPipeline: GitlabPipeline | null, status?: { code: DojoStatusCode, message: string } }> {
-        const pipelines = await SharedGitlabManager.getRepositoryPipelines(repositoryId, 'main');
-        if ( pipelines.length > 0 ) {
-            const lastPipeline = pipelines[0];
-            if ( lastPipeline.status != GitlabPipelineStatus.SUCCESS ) {
-                return {
-                    isPublishable: false,
-                    lastPipeline : lastPipeline,
-                    status       : {
-                        code   : DojoStatusCode.ASSIGNMENT_PUBLISH_PIPELINE_FAILED,
-                        message: `Last pipeline status is not "${ GitlabPipelineStatus.SUCCESS }" but "${ lastPipeline.status }".`
-                    }
-                };
-            } else {
-                return {
-                    isPublishable: true,
-                    lastPipeline : lastPipeline
-                };
-            }
-        } else {
-            return {
-                isPublishable: false,
-                lastPipeline : null,
-                status       : {
-                    code   : DojoStatusCode.ASSIGNMENT_PUBLISH_NO_PIPELINE,
-                    message: 'No pipeline found for this assignment.'
-                }
-            };
-        }
-    }
-}
-
-
-export default new SharedAssignmentHelper();
\ No newline at end of file
diff --git a/helpers/Dojo/SharedExerciseHelper.ts b/helpers/Dojo/SharedExerciseHelper.ts
deleted file mode 100644
index 97ccf7c9a39682ba8b14fa65b54a89d9898ebf3c..0000000000000000000000000000000000000000
--- a/helpers/Dojo/SharedExerciseHelper.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-class SharedExerciseHelper {}
-
-
-export default new SharedExerciseHelper();
\ No newline at end of file
diff --git a/helpers/Json5FileValidator.ts b/helpers/Json5FileValidator.ts
deleted file mode 100644
index c9be717bbf249bdb6230b187deb1e1fc948a2274..0000000000000000000000000000000000000000
--- a/helpers/Json5FileValidator.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import JSON5            from 'json5';
-import fs               from 'fs';
-import { z, ZodError }  from 'zod';
-import { fromZodError } from 'zod-validation-error';
-
-
-class Json5FileValidator {
-    validateFile<T>(schema: z.ZodType<T>, filePathOrStr: string, isFile: boolean = true, resultSanitizer: (value: T) => T = value => value): { content: T | undefined, isValid: boolean, error: string | null } {
-        let parsedInput: T;
-
-        try {
-            parsedInput = JSON5.parse(isFile ? fs.readFileSync(filePathOrStr, 'utf8') : filePathOrStr);
-        } catch ( error ) {
-            return {
-                content: undefined,
-                isValid: false,
-                error  : `JSON5 invalid : ${ JSON.stringify(error) }`
-            };
-        }
-
-        try {
-            return {
-                content: resultSanitizer(schema.parse(parsedInput) as unknown as T),
-                isValid: true,
-                error  : null
-            };
-        } catch ( error ) {
-            if ( error instanceof ZodError ) {
-                return {
-                    content: parsedInput,
-                    isValid: false,
-                    error  : fromZodError(error).toString()
-                };
-            }
-
-            return {
-                content: parsedInput,
-                isValid: false,
-                error  : `Unknown error : ${ JSON.stringify(error) }`
-            };
-        }
-    }
-}
-
-
-export default new Json5FileValidator();
\ No newline at end of file
diff --git a/helpers/LazyVal.ts b/helpers/LazyVal.ts
deleted file mode 100644
index 4613c4b535706f5853b060279ce46a957e3c3030..0000000000000000000000000000000000000000
--- a/helpers/LazyVal.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-class LazyVal<T> {
-    private val: T | undefined = undefined;
-
-    constructor(private valLoader: () => Promise<T> | T) {}
-
-    get value(): Promise<T> {
-        return new Promise<T>((resolve) => {
-            if ( this.val === undefined ) {
-                Promise.resolve(this.valLoader()).then((value: T) => {
-                    this.val = value;
-                    resolve(value);
-                });
-            } else {
-                resolve(this.val);
-            }
-        });
-    }
-
-    reset() {
-        this.val = undefined;
-    }
-
-    get isValueLoaded(): boolean {
-        return this.val !== undefined;
-    }
-}
-
-
-export default LazyVal;
diff --git a/helpers/Toolbox.ts b/helpers/Toolbox.ts
deleted file mode 100644
index 8a76bebb202e6bcbe46944e562924effdeb26afe..0000000000000000000000000000000000000000
--- a/helpers/Toolbox.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import fs   from 'fs/promises';
-import path from 'path';
-
-
-class Toolbox {
-    public urlToPath(url: string): string {
-        return url.replace(/^([a-z]{3,5}:\/{2})?[a-z.@]+(:[0-9]{1,5})?.(.*)/, '$3').replace('.git', '');
-    }
-
-    /*
-     Source of getAllFiles and getTotalSize (modified for this project): https://coderrocketfuel.com/article/get-the-total-size-of-all-files-in-a-directory-using-node-js
-     */
-    private async getAllFiles(dirPath: string, arrayOfFiles: Array<string> = []): Promise<Array<string>> {
-        const files = await fs.readdir(dirPath);
-
-        await Promise.all(files.map(async file => {
-            if ( (await fs.stat(dirPath + '/' + file)).isDirectory() ) {
-                arrayOfFiles = await this.getAllFiles(dirPath + '/' + file, arrayOfFiles);
-            } else {
-                arrayOfFiles.push(path.join(dirPath, file));
-            }
-        }));
-
-        return arrayOfFiles;
-    }
-
-    private async getTotalSize(directoryPath: string): Promise<number> {
-        const arrayOfFiles = await this.getAllFiles(directoryPath);
-
-        let totalSize = 0;
-
-        for ( const filePath of arrayOfFiles ) {
-            totalSize += (await fs.stat(filePath)).size;
-        }
-
-        return totalSize;
-    }
-
-    get fs() {
-        return {
-            getAllFiles : this.getAllFiles.bind(this),
-            getTotalSize: this.getTotalSize.bind(this)
-        };
-    }
-
-    public snakeToCamel(str: string): string {
-        return str.toLowerCase().replace(/([-_][a-z])/g, (group: string) => group.toUpperCase().replace('-', '').replace('_', ''));
-    }
-
-    public getKeysWithPrefix(obj: object, prefix: string): Array<string> {
-        return Object.keys(obj).filter(key => key.startsWith(prefix));
-    }
-}
-
-
-export default new Toolbox();
diff --git a/helpers/TypeScriptExtensions.ts b/helpers/TypeScriptExtensions.ts
deleted file mode 100644
index fd730ad37daa50a1b6e855efaf3c48ce739faa05..0000000000000000000000000000000000000000
--- a/helpers/TypeScriptExtensions.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-declare global {
-    interface BigInt {
-        toJSON: () => string;
-    }
-
-
-    interface Array<T> {
-        removeObjectDuplicates: (getProperty: (item: T) => unknown) => Array<T>;
-    }
-
-
-    interface String {
-        toBoolean: () => boolean;
-        capitalizingFirstLetter: () => string;
-        capitalizeName: () => string;
-        convertWithEnvVars: () => string;
-    }
-}
-
-function registerAll() {
-    registerBigIntJson();
-    registerArrayRemoveObjectDuplicates();
-    registerStringToBoolean();
-    registerStringCapitalizingFirstLetter();
-    registerStringCapitalizeName();
-    registerStringConvertWithEnvVars();
-}
-
-function registerBigIntJson() {
-    BigInt.prototype.toJSON = function () {
-        return this.toString();
-    };
-}
-
-function registerArrayRemoveObjectDuplicates() {
-    Array.prototype.removeObjectDuplicates = function <T>(this: Array<T>, getProperty: (item: T) => unknown): Array<T> {
-        return this.reduce((accumulator: Array<T>, current: T) => {
-            if ( !accumulator.find((item: T) => getProperty(item) === getProperty(current)) ) {
-                accumulator.push(current);
-            }
-            return accumulator;
-        }, Array<T>());
-    };
-}
-
-function registerStringToBoolean() {
-    String.prototype.toBoolean = function (this: string): boolean {
-        const tmp = this.toLowerCase().trim();
-        return tmp === 'true' || tmp === '1';
-    };
-}
-
-function registerStringCapitalizingFirstLetter() {
-    String.prototype.capitalizingFirstLetter = function (this: string): string {
-        return this.charAt(0).toUpperCase() + this.slice(1);
-    };
-}
-
-function registerStringCapitalizeName() {
-    String.prototype.capitalizeName = function (this: string): string {
-        return this.trim().replace(/(?:^|\s|-)\S/g, s => s.toUpperCase());
-    };
-}
-
-function registerStringConvertWithEnvVars() {
-    String.prototype.convertWithEnvVars = function (this: string): string {
-        return this.replace(/\${?([a-zA-Z0-9_]+)}?/g, (_match: string, p1: string) => {
-            return process.env[p1] || '';
-        });
-    };
-}
-
-registerAll();
-
-
-export default null;
\ No newline at end of file
diff --git a/helpers/recursiveFilesStats/README.md b/helpers/recursiveFilesStats/README.md
deleted file mode 100644
index f2e98d4319eb3ce841bd1b2bb57c1b393aa8f483..0000000000000000000000000000000000000000
--- a/helpers/recursiveFilesStats/README.md
+++ /dev/null
@@ -1,148 +0,0 @@
-Source: recursive-readdir-files
-===
-Modified for Dojo
-===
-
-## Usage
-
-```js
-import recursiveReaddirFiles from 'recursive-readdir-files';
-
-
-const files = await recursiveReaddirFiles(process.cwd(), {
-    ignored: /\/(node_modules|\.git)/
-});
-
-// `files` is an array
-console.log(files);
-// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
-// [
-//   {
-//     dev: 16777233,
-//     mode: 33188,
-//     nlink: 1,
-//     uid: 501,
-//     gid: 20,
-//     rdev: 0,
-//     blksize: 4096,
-//     ino: 145023089,
-//     size: 89,
-//     blocks: 8,
-//     atimeMs: 1649303678077.934,
-//     mtimeMs: 1649303676847.1777,
-//     ctimeMs: 1649303676847.1777,
-//     birthtimeMs: 1649301118132.6782,
-//     atime: 2022-04-07T03:54:38.078Z,
-//     mtime: 2022-04-07T03:54:36.847Z,
-//     ctime: 2022-04-07T03:54:36.847Z,
-//     birthtime: 2022-04-07T03:11:58.133Z,
-//     name: 'watch.ts',
-//     path: '/Users/xxx/watch.ts',
-//     ext: 'ts'
-//   },
-//   // ...
-// ]
-```
-
-Or
-
-```js
-recursiveReaddirFiles(process.cwd(), {
-    ignored: /\/(node_modules|\.git)/
-}, (filepath, state) => {
-    console.log(filepath);
-    // 👉 /Users/xxx/watch.ts
-    console.log(state.isFile());      // 👉 true
-    console.log(state.isDirectory()); // 👉 false
-    console.log(state);
-    // ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
-    // {
-    //   dev: 16777233,
-    //   mode: 33188,
-    //   nlink: 1,
-    //   uid: 501,
-    //   gid: 20,
-    //   rdev: 0,
-    //   blksize: 4096,
-    //   ino: 145023089,
-    //   size: 89,
-    //   blocks: 8,
-    //   atimeMs: 1649303678077.934,
-    //   mtimeMs: 1649303676847.1777,
-    //   ctimeMs: 1649303676847.1777,
-    //   birthtimeMs: 1649301118132.6782,
-    //   atime: 2022-04-07T03:54:38.078Z,
-    //   mtime: 2022-04-07T03:54:36.847Z,
-    //   ctime: 2022-04-07T03:54:36.847Z,
-    //   birthtime: 2022-04-07T03:11:58.133Z,
-    //   name: 'watch.ts',
-    //   path: '/Users/xxx/watch.ts',
-    //   ext: 'ts'
-    // }
-})
-```
-
-## Options
-
-```ts
-export interface RecursiveReaddirFilesOptions {
-    /**
-     * Ignore files
-     * @example `/\/(node_modules|\.git)/`
-     */
-    ignored?: RegExp;
-    /**
-     * Specifies a list of `glob` patterns that match files to be included in compilation.
-     * @example `/(\.json)$/`
-     */
-    include?: RegExp;
-    /**
-     * Specifies a list of files to be excluded from compilation.
-     * @example `/(package\.json)$/`
-     */
-    exclude?: RegExp;
-    /** Provide filtering methods to filter data. */
-    filter?: (item: IFileDirStat) => boolean;
-    /** Do not give the absolute path but the relative one from the root folder */
-    replacePathByRelativeOne?: boolean;
-    /** Remove stats that are not necessary for transfert */
-    liteStats?: boolean;
-}
-```
-
-## Result
-
-```ts
-import fs from 'node:fs';
-
-
-export interface IFileDirStat extends Partial<fs.Stats> {
-    /**
-     * @example `/a/sum.jpg` => `sum.jpg`
-     */
-    name: string;
-    /**
-     * @example `/basic/src/utils/sum.ts`
-     */
-    path: string;
-    /**
-     * @example `/a/b.jpg` => `jpg`
-     */
-    ext?: string;
-}
-
-
-declare type Callback = (filepath: string, stat: IFileDirStat) => void;
-export default function recursiveReaddirFiles(rootPath: string, options?: RecursiveReaddirFilesOptions, callback?: Callback): Promise<IFileDirStat[]>;
-export { recursiveReaddirFiles };
-export declare const getStat: (filepath: string) => Promise<IFileDirStat>;
-/**
- * Get ext
- * @param {String} filePath `/a/b.jpg` => `jpg`
- */
-export declare const getExt: (filePath: string) => string;
-```
-
-## License
-
-Licensed under the MIT License.
diff --git a/helpers/recursiveFilesStats/RecursiveFilesStats.ts b/helpers/recursiveFilesStats/RecursiveFilesStats.ts
deleted file mode 100644
index a571aaac797de782ee6bc95d33ad9e75ee03b647..0000000000000000000000000000000000000000
--- a/helpers/recursiveFilesStats/RecursiveFilesStats.ts
+++ /dev/null
@@ -1,146 +0,0 @@
-import fs   from 'node:fs';
-import path from 'node:path';
-
-
-export interface RecursiveReaddirFilesOptions {
-    /**
-     * Ignore files
-     * @example `/\/(node_modules|\.git)/`
-     */
-    ignored?: RegExp;
-    /**
-     * Specifies a list of `glob` patterns that match files to be included in compilation.
-     * @example `/(\.json)$/`
-     */
-    include?: RegExp;
-    /**
-     * Specifies a list of files to be excluded from compilation.
-     * @example `/(package\.json)$/`
-     */
-    exclude?: RegExp;
-    /** Provide filtering methods to filter data. */
-    filter?: (item: IFileDirStat) => boolean;
-    /** Do not give the absolute path but the relative one from the root folder */
-    replacePathByRelativeOne?: boolean;
-    /** Remove stats that are not necessary for transfert */
-    liteStats?: boolean;
-}
-
-
-export interface IFileDirStat extends Partial<fs.Stats> {
-    /**
-     * @example `/a/sum.jpg` => `sum.jpg`
-     */
-    name: string;
-    /**
-     * @example `/basic/src/utils/sum.ts`
-     */
-    path: string;
-    /**
-     * @example `/a/b.jpg` => `jpg`
-     */
-    ext?: string;
-}
-
-
-type Callback = (filepath: string, stat: IFileDirStat) => void;
-
-
-class RecursiveFilesStats {
-    async explore(rootPath: string, options: RecursiveReaddirFilesOptions = {}, callback?: Callback): Promise<IFileDirStat[]> {
-        return this.getFiles(`${ path.resolve(rootPath) }/`, rootPath, options, [], callback);
-    }
-
-    private async getFiles(absoluteBasePath: string, rootPath: string, options: RecursiveReaddirFilesOptions = {}, files: IFileDirStat[] = [], callback?: Callback): Promise<IFileDirStat[]> {
-        const {
-                  ignored, include, exclude, filter
-              } = options;
-        const filesData = await fs.promises.readdir(rootPath);
-        const fileDir: IFileDirStat[] = filesData.map((file) => ({
-            name: file, path: path.join(rootPath, file)
-        })).filter((item) => {
-            if ( include && include.test(item.path) ) {
-                return true;
-            }
-            if ( exclude && exclude.test(item.path) ) {
-                return false;
-            }
-            if ( ignored ) {
-                return !ignored.test(item.path);
-            }
-            return true;
-        });
-        if ( callback ) {
-            fileDir.map(async (item: IFileDirStat) => {
-                const stat = await this.getStat(item.path, absoluteBasePath, options);
-                if ( stat.isDirectory!() ) {
-                    await this.getFiles(absoluteBasePath, item.path, options, [], callback);
-                }
-                callback(item.path, stat);
-            });
-        } else {
-            await Promise.all(fileDir.map(async (item: IFileDirStat) => {
-                const stat = await this.getStat(item.path, absoluteBasePath, options);
-                if ( stat.isDirectory!() ) {
-                    const arr = await this.getFiles(absoluteBasePath, item.path, options, []);
-                    files = files.concat(arr);
-                } else if ( stat.isFile!() ) {
-                    files.push(stat);
-                }
-            }));
-        }
-        return files.filter((item) => {
-            if ( filter && typeof filter === 'function' ) {
-                return filter(item);
-            }
-            return true;
-        });
-    }
-
-    private async getStat(filepath: string, absoluteRootPath: string, options: RecursiveReaddirFilesOptions): Promise<IFileDirStat> {
-        const stat = (await fs.promises.stat(filepath)) as IFileDirStat;
-        stat.ext = '';
-        if ( stat.isFile!() ) {
-            stat.ext = this.getExt(filepath);
-            stat.name = path.basename(filepath);
-            stat.path = path.resolve(filepath);
-        }
-
-        if ( options.replacePathByRelativeOne && stat.path ) {
-            stat.path = stat.path.replace(absoluteRootPath, '');
-        }
-
-        if ( options.liteStats ) {
-            delete stat.dev;
-            delete stat.nlink;
-            delete stat.uid;
-            delete stat.gid;
-            delete stat.rdev;
-            delete stat.blksize;
-            delete stat.ino;
-            delete stat.blocks;
-            delete stat.atimeMs;
-            delete stat.mtimeMs;
-            delete stat.ctimeMs;
-            delete stat.birthtimeMs;
-            delete stat.atime;
-            //delete stat.mtime;
-            delete stat.ctime;
-            //delete stat.birthtime;
-            //delete stat.mode;
-        }
-
-        return stat;
-    }
-
-    /**
-     * Get ext
-     * @param {String} filePath `/a/b.jpg` => `jpg`
-     */
-    private getExt(filePath: string): string {
-        return path.extname(filePath).replace(/^\./, '').toLowerCase();
-    }
-}
-
-
-export default new RecursiveFilesStats();
diff --git a/logging/WinstonLogger.ts b/logging/WinstonLogger.ts
deleted file mode 100644
index 941e5388ed95b1f281c21f5d2bf2c0c9217ae10a..0000000000000000000000000000000000000000
--- a/logging/WinstonLogger.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-import winston        from 'winston';
-import SharedConfig   from '../config/SharedConfig';
-import * as Transport from 'winston-transport';
-
-
-const levels = {
-    error: 0,
-    warn : 1,
-    info : 2,
-    http : 3,
-    debug: 4
-};
-
-const colors = {
-    error: 'red',
-    warn : 'orange',
-    info : 'green',
-    http : 'magenta',
-    debug: 'blue'
-};
-winston.addColors(colors);
-
-const format = winston.format.combine(winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), winston.format(info => ({
-    ...info,
-    level: info.level.toUpperCase()
-}))(), SharedConfig.production ? winston.format.uncolorize() : winston.format.colorize({ all: true }), winston.format.prettyPrint(), winston.format.errors({ stack: true }), winston.format.align(), winston.format.printf((info) => `[${ info.timestamp }] (${ process.pid }) ${ info.level } ${ info.message } ${ info.metadata ? `\n${ JSON.stringify(info.metadata) }` : '' } ${ info.stack ? `\n${ info.stack }` : '' } `));
-
-const commonTransportOptions = {
-    handleRejections: true,
-    handleExceptions: true
-};
-
-let transports: Array<Transport> = [ new winston.transports.Console({
-                                                                        ...commonTransportOptions,
-                                                                        level: 'debug'
-                                                                    }) ];
-
-if ( SharedConfig.production ) {
-    const commonFileOptions = {
-        ...commonTransportOptions,
-        maxsize : 5242880, // 5MB
-        maxFiles: 100,
-        tailable: true
-    };
-
-    transports = transports.concat([ new winston.transports.File({
-                                                                     ...commonFileOptions,
-                                                                     filename: `${ SharedConfig.logsFolder }/error.log`,
-                                                                     level   : 'error'
-                                                                 }), new winston.transports.File({
-                                                                                                     ...commonFileOptions,
-                                                                                                     filename: `${ SharedConfig.logsFolder }/all.log`,
-                                                                                                     level   : 'debug'
-                                                                                                 }) ]);
-}
-
-const logger = winston.createLogger({
-                                        levels,
-                                        format,
-                                        transports,
-                                        exitOnError: false
-                                    });
-
-export default logger;
diff --git a/managers/SharedGitlabManager.ts b/managers/SharedGitlabManager.ts
deleted file mode 100644
index 68ff699a036044872cb7f33ead08782afbbdb830..0000000000000000000000000000000000000000
--- a/managers/SharedGitlabManager.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import axios          from 'axios';
-import GitlabPipeline from '../types/Gitlab/GitlabPipeline';
-import GitlabRoute    from '../types/Gitlab/GitlabRoute';
-import SharedConfig   from '../config/SharedConfig';
-import GitlabToken    from '../types/Gitlab/GitlabToken';
-
-
-class GitlabManager {
-    private getApiUrl(route: GitlabRoute): string {
-        return `${ SharedConfig.gitlab.apiURL }${ route }`;
-    }
-
-    async getTokens(codeOrRefresh: string, isRefresh: boolean = false, clientSecret: string = ''): Promise<GitlabToken> {
-        const response = await axios.post<GitlabToken>(SharedConfig.login.gitlab.url.token, {
-            client_id    : SharedConfig.login.gitlab.client.id,
-            client_secret: clientSecret,
-            grant_type   : isRefresh ? 'refresh_token' : 'authorization_code',
-            refresh_token: codeOrRefresh,
-            code         : codeOrRefresh,
-            redirect_uri : SharedConfig.login.gitlab.url.redirect
-        });
-
-        return response.data;
-    }
-
-    async getRepositoryPipelines(repoId: number, branch: string = 'main'): Promise<Array<GitlabPipeline>> {
-        const response = await axios.get<Array<GitlabPipeline>>(this.getApiUrl(GitlabRoute.REPOSITORY_PIPELINES).replace('{{id}}', String(repoId)), {
-            params: {
-                ref: branch
-            }
-        });
-
-        return response.data;
-    }
-}
-
-
-export default new GitlabManager();
diff --git a/models/Tag.ts b/models/Tag.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c12d301d97fc890baf8eca89d783fa405ab85189
--- /dev/null
+++ b/models/Tag.ts
@@ -0,0 +1,17 @@
+import { CommitSchema } from '@gitbeaker/rest';
+import Assignment       from './Assignment';
+import Exercise         from './Exercise';
+
+
+interface Tag {
+    name: string;
+    type: 'Language' | 'Framework' | 'Theme' | 'UserDefined';
+
+    exercise: Exercise | undefined;
+    assignment: Assignment | undefined;
+
+    correctionCommit: CommitSchema | undefined;
+}
+
+export default Tag;
+	
\ No newline at end of file
diff --git a/types/Dojo/ApiRoute.ts b/types/Dojo/ApiRoute.ts
index ef63323d1381f1af9f8acc1f3da044602b195fba..612488c70f97f3b4fa91469332cd9e21278dd3a8 100644
--- a/types/Dojo/ApiRoute.ts
+++ b/types/Dojo/ApiRoute.ts
@@ -12,6 +12,10 @@ enum ApiRoute {
     EXERCISE_CREATE                     = '/assignments/{{assignmentNameOrUrl}}/exercises',
     EXERCISE_ASSIGNMENT                 = '/exercises/{{exerciseIdOrUrl}}/assignment',
     EXERCISE_RESULTS                    = '/exercises/{{exerciseIdOrUrl}}/results'
+    ADD_TAG                      = '/tags',
+    DELETE_TAG                   = '/tags/{tagid}',
+    PROPOSE_TAG                  = '/tags/proposals',
+    ANSWER_TAG_PROPOSAL          = '/tags/proposals/{tagProposalName}'
 }
 
 
diff --git a/types/Dojo/AssignmentCheckerError.ts b/types/Dojo/AssignmentCheckerError.ts
deleted file mode 100644
index 34df2a8d771aad43750bb78ce490bdc3202f1022..0000000000000000000000000000000000000000
--- a/types/Dojo/AssignmentCheckerError.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-enum ExerciseCheckerError {
-    DOCKER_DAEMON_NOT_RUNNING       = 200,
-    REQUIRED_FILES_MISSING          = 201,
-    ASSIGNMENT_FILE_SCHEMA_ERROR    = 202,
-    IMMUTABLE_PATH_NOT_FOUND        = 203,
-    IMMUTABLE_PATH_IS_DIRECTORY     = 204,
-    IMMUTABLE_PATH_IS_NOT_DIRECTORY = 205,
-    COMPOSE_FILE_YAML_ERROR         = 206,
-    COMPOSE_FILE_SCHEMA_ERROR       = 207,
-    COMPOSE_FILE_CONTAINER_MISSING  = 208,
-    COMPOSE_FILE_VOLUME_MISSING     = 209,
-    DOCKERFILE_NOT_FOUND            = 210,
-    COMPOSE_RUN_SUCCESSFULLY        = 211, // Yes, this is an error
-}
-
-
-/**
- * Codes that are unusable for historic reasons:
- * None
- */
-
-
-export default ExerciseCheckerError;
\ No newline at end of file
diff --git a/types/Dojo/AssignmentFile.ts b/types/Dojo/AssignmentFile.ts
deleted file mode 100644
index df09d53ae249bf3614debd251630eb10e96a5c0b..0000000000000000000000000000000000000000
--- a/types/Dojo/AssignmentFile.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import ImmutableFileDescriptor from './ImmutableFileDescriptor';
-import { z }                   from 'zod';
-
-
-const AssignmentFile = z.object({
-                                    dojoAssignmentVersion: z.number(),
-                                    version              : z.number(),
-                                    immutable            : z.array(ImmutableFileDescriptor.transform(value => value as ImmutableFileDescriptor)),
-                                    result               : z.object({
-                                                                        container: z.string(),
-                                                                        volume   : z.string().optional()
-                                                                    })
-                                }).strict();
-
-
-type AssignmentFile = z.infer<typeof AssignmentFile>;
-
-
-export default AssignmentFile;
\ No newline at end of file
diff --git a/types/Dojo/DojoBackendResponse.ts b/types/Dojo/DojoBackendResponse.ts
deleted file mode 100644
index 6c6eed91a45e42e0ff784baedeed2c76833236d3..0000000000000000000000000000000000000000
--- a/types/Dojo/DojoBackendResponse.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-interface DojoBackendResponse<T> {
-    timestamp: string;
-    code: number;
-    description: string;
-    sessionToken: string | null;
-    data: T;
-}
-
-
-export default DojoBackendResponse;
\ No newline at end of file
diff --git a/types/Dojo/DojoStatusCode.ts b/types/Dojo/DojoStatusCode.ts
deleted file mode 100644
index 16f152daedf7a9f3b8154ea632dce404b8ccc8cf..0000000000000000000000000000000000000000
--- a/types/Dojo/DojoStatusCode.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-enum DojoStatusCode {
-    LOGIN_FAILED                        = 1,
-    REFRESH_TOKENS_FAILED               = 2,
-    CLIENT_NOT_SUPPORTED                = 100,
-    CLIENT_VERSION_NOT_SUPPORTED        = 110,
-    ASSIGNMENT_PUBLISH_NO_PIPELINE      = 200,
-    ASSIGNMENT_PUBLISH_PIPELINE_FAILED  = 201,
-    ASSIGNMENT_CREATION_GITLAB_ERROR    = 202,
-    ASSIGNMENT_CREATION_INTERNAL_ERROR  = 203,
-    ASSIGNMENT_EXERCISE_NOT_RELATED     = 204,
-    ASSIGNMENT_NOT_PUBLISHED            = 205,
-    EXERCISE_CORRECTION_NOT_EXIST       = 206,
-    EXERCISE_CORRECTION_ALREADY_EXIST   = 207,
-    EXERCISE_CREATION_GITLAB_ERROR      = 302,
-    EXERCISE_CREATION_INTERNAL_ERROR    = 303,
-    MAX_EXERCISE_PER_ASSIGNMENT_REACHED = 304
-}
-
-
-export default DojoStatusCode;
\ No newline at end of file
diff --git a/types/Dojo/ExerciseCheckerError.ts b/types/Dojo/ExerciseCheckerError.ts
deleted file mode 100644
index 45810d0c9e34dcdb0c37fcf64525bcad29edbbcb..0000000000000000000000000000000000000000
--- a/types/Dojo/ExerciseCheckerError.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-enum ExerciseCheckerError {
-    EXERCISE_ASSIGNMENT_GET_ERROR          = 200,
-    DOCKER_COMPOSE_RUN_ERROR               = 201,
-    DOCKER_COMPOSE_LOGS_ERROR              = 202,
-    DOCKER_COMPOSE_DOWN_ERROR              = 203,
-    EXERCISE_RESULTS_FOLDER_TOO_BIG        = 204,
-    EXERCISE_RESULTS_FILE_SCHEMA_NOT_VALID = 206,
-    UPLOAD                                 = 207,
-    DOCKER_COMPOSE_REMOVE_DANGLING_ERROR   = 208
-}
-
-
-/**
- * Codes that are unusable for historic reasons:
- * - 205: EXERCISE_RESULTS_FILE_NOT_FOUND => From the version 2.2.0 this error is not possible anymore because the results file is now optional
- */
-
-
-export default ExerciseCheckerError;
\ No newline at end of file
diff --git a/types/Dojo/ExerciseResultsFile.ts b/types/Dojo/ExerciseResultsFile.ts
deleted file mode 100644
index 135a532d11623c74389f049ec83da16a2c5988f2..0000000000000000000000000000000000000000
--- a/types/Dojo/ExerciseResultsFile.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import Icon  from '../Icon';
-import { z } from 'zod';
-
-
-const ExerciseResultsFile = z.object({
-                                         success: z.boolean().optional(),
-
-                                         containerExitCode: z.number().optional(),
-
-                                         successfulTests: z.number().optional(),
-                                         failedTests    : z.number().optional(),
-
-                                         successfulTestsList: z.array(z.string()).optional(),
-                                         failedTestsList    : z.array(z.string()).optional(),
-
-                                         otherInformations: z.array(z.object({
-                                                                                 name               : z.string(),
-                                                                                 description        : z.string().optional(),
-                                                                                 icon               : z.enum(Object.keys(Icon) as [ firstKey: string, ...otherKeys: Array<string> ]).optional(),
-                                                                                 itemsOrInformations: z.union([ z.array(z.string()), z.string() ])
-                                                                             }))
-                                         .optional()
-                                     }).strict().transform(value => {
-    if ( value.successfulTests === undefined && value.successfulTestsList !== undefined ) {
-        value.successfulTests = value.successfulTestsList.length;
-    }
-
-    if ( value.failedTests === undefined && value.failedTestsList !== undefined ) {
-        value.failedTests = value.failedTestsList.length;
-    }
-
-    return value;
-});
-
-
-type ExerciseResultsFile = z.infer<typeof ExerciseResultsFile>;
-
-
-export default ExerciseResultsFile;
\ No newline at end of file
diff --git a/types/Dojo/ImmutableFileDescriptor.ts b/types/Dojo/ImmutableFileDescriptor.ts
deleted file mode 100644
index 27f66a1104340bc404b6788a88b06b776df8f5e4..0000000000000000000000000000000000000000
--- a/types/Dojo/ImmutableFileDescriptor.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { z } from 'zod';
-
-
-const ImmutableFileDescriptor = z.object({
-                                             description: z.string().optional(),
-                                             path       : z.string(),
-                                             isDirectory: z.boolean().optional()
-                                         });
-
-
-type ImmutableFileDescriptor = z.infer<typeof ImmutableFileDescriptor>;
-
-
-export default ImmutableFileDescriptor;
\ No newline at end of file
diff --git a/types/Gitlab/GitlabAccessLevel.ts b/types/Gitlab/GitlabAccessLevel.ts
deleted file mode 100644
index be06ffd009103feb9f30a4e18250c2fcf978527b..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabAccessLevel.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-enum GitlabAccessLevel {
-    GUEST      = 10,
-    REPORTER   = 20,
-    DEVELOPER  = 30,
-    MAINTAINER = 40,
-    OWNER      = 50,
-    ADMIN      = 60
-}
-
-
-export default GitlabAccessLevel;
diff --git a/types/Gitlab/GitlabCommit.ts b/types/Gitlab/GitlabCommit.ts
deleted file mode 100644
index 5f94c2e431b220b4247e0dc3bf0222fba14f2a1c..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabCommit.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-interface GitlabCommit {
-    id: string;
-    short_id: string;
-    created_at: string;
-    parent_ids: Array<string>;
-    title: string;
-    message: string;
-    author_name: string;
-    author_email: string;
-    authored_date: string;
-    committer_name: string;
-    committer_email: string;
-    committed_date: string;
-}
-
-
-export default GitlabCommit;
\ No newline at end of file
diff --git a/types/Gitlab/GitlabFile.ts b/types/Gitlab/GitlabFile.ts
deleted file mode 100644
index 05205d4f1e28d5d04e60ae304acb02f3ddcb0d02..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabFile.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-interface GitlabFile {
-    file_name: string,
-    file_path: string,
-    size: number,
-    encoding: string,
-    content_sha256: string,
-    ref: string,
-    blob_id: string,
-    commit_id: string,
-    last_commit_id: string,
-    execute_filemode: boolean,
-    content: string,
-}
-
-
-export default GitlabFile;
\ No newline at end of file
diff --git a/types/Gitlab/GitlabGroup.ts b/types/Gitlab/GitlabGroup.ts
deleted file mode 100644
index 812f8838b5e00eb50cea0a282e3e26dc20344fef..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabGroup.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-interface GitlabGroup {
-    group_id: number,
-    group_name: string,
-    group_full_path: string,
-    group_access_level: number,
-    expires_at: string
-}
-
-
-export default GitlabGroup;
\ No newline at end of file
diff --git a/types/Gitlab/GitlabMember.ts b/types/Gitlab/GitlabMember.ts
deleted file mode 100644
index 6c7c7163f73104221de918af4ceb09d4a55c98e2..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabMember.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import GitlabUser from './GitlabUser';
-
-
-interface GitlabMember extends GitlabUser {
-    access_level: number,
-    created_at: string,
-    created_by: GitlabUser,
-    expires_at: string | null
-}
-
-
-export default GitlabMember;
\ No newline at end of file
diff --git a/types/Gitlab/GitlabMilestone.ts b/types/Gitlab/GitlabMilestone.ts
deleted file mode 100644
index a7285cd9ee3683aeaf4ebc1ea85ab778af1e970c..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabMilestone.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-interface GitlabMilestone {
-    id: number;
-    iid: number;
-    project_id: number;
-    title: string;
-    description: string;
-    state: string;
-    created_at: string;
-    updated_at: string;
-    due_date: string;
-    start_date: string;
-    web_url: string;
-    issue_stats: {
-        total: number; closed: number;
-    };
-}
-
-
-export default GitlabMilestone;
\ No newline at end of file
diff --git a/types/Gitlab/GitlabNamespace.ts b/types/Gitlab/GitlabNamespace.ts
deleted file mode 100644
index 4d892afb58d81138a6b204124fc5b2ed6526eeca..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabNamespace.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-interface GitlabNamespace {
-    id: number,
-    name: string,
-    path: string,
-    kind: string,
-    full_path: string,
-    parent_id: number,
-    avatar_url: string,
-    web_url: string
-}
-
-
-export default GitlabNamespace;
\ No newline at end of file
diff --git a/types/Gitlab/GitlabPipeline.ts b/types/Gitlab/GitlabPipeline.ts
deleted file mode 100644
index 1ee75b643b458b1f0c924f5d47f7ae0f0f88ddb0..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabPipeline.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import GitlabPipelineStatus from './GitlabPipelineStatus';
-import GitlabPipelineSource from './GitlabPipelineSource';
-import GitlabUser           from './GitlabUser';
-
-
-interface GitlabPipeline {
-    id: number,
-    iid: number,
-    project_id: number,
-    status: GitlabPipelineStatus,
-    source: GitlabPipelineSource,
-    ref: string,
-    sha: string,
-    before_sha: string,
-    tag: boolean,
-    name: string,
-    yaml_errors: string | null,
-    user: GitlabUser,
-    web_url: string,
-    created_at: string,
-    updated_at: string,
-    started_at: string | null,
-    finished_at: string | null,
-    committed_at: string | null,
-    duration: number | null,
-    queued_duration: number | null,
-    coverage: string | null,
-}
-
-
-export default GitlabPipeline;
\ No newline at end of file
diff --git a/types/Gitlab/GitlabPipelineSource.ts b/types/Gitlab/GitlabPipelineSource.ts
deleted file mode 100644
index 33253b07ded1850dfcce309971e84836e417a615..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabPipelineSource.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-enum GitlabPipelineSource {
-    PUSH                      = 'push',
-    WEB                       = 'web',
-    TRIGGER                   = 'trigger',
-    SCHEDULE                  = 'schedule',
-    API                       = 'api',
-    EXTERNAL                  = 'external',
-    PIPELINE                  = 'pipeline',
-    CHAT                      = 'chat',
-    WEBIDE                    = 'webide',
-    MERGE_REQUEST             = 'merge_request_event',
-    EXTERNAL_PULL_REQUEST     = 'external_pull_request_event',
-    PARENT_PIPELINE           = 'parent_pipeline',
-    ON_DEMAND_DAST_SCAN       = 'ondemand_dast_scan',
-    ON_DEMAND_DAST_VALIDATION = 'ondemand_dast_validation',
-}
-
-
-export default GitlabPipelineSource;
diff --git a/types/Gitlab/GitlabPipelineStatus.ts b/types/Gitlab/GitlabPipelineStatus.ts
deleted file mode 100644
index cd6d7b268b951785fccfe11b6a82f3b6376b566a..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabPipelineStatus.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-enum GitlabPipelineStatus {
-    CREATED              = 'created',
-    WAITING_FOR_RESOURCE = 'waiting_for_resource',
-    PREPARING            = 'preparing',
-    PENDING              = 'pending',
-    RUNNING              = 'running',
-    SUCCESS              = 'success',
-    FAILED               = 'failed',
-    CANCELED             = 'canceled',
-    SKIPPED              = 'skipped',
-    MANUAL               = 'manual',
-    SCHEDULED            = 'scheduled'
-}
-
-
-export default GitlabPipelineStatus;
diff --git a/types/Gitlab/GitlabProfile.ts b/types/Gitlab/GitlabProfile.ts
deleted file mode 100644
index aa7506dbddcf7051a29c118d69fc26d1f7fb55bb..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabProfile.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import GitlabUser from './GitlabUser';
-
-
-interface GitlabProfile extends GitlabUser {
-    created_at: string,
-    bio: string,
-    location: string,
-    public_email: string,
-    skype: string,
-    linkedin: string,
-    twitter: string,
-    discord: string,
-    website_url: string,
-    organization: string,
-    job_title: string,
-    pronouns: string,
-    bot: boolean,
-    work_information: string,
-    local_time: string,
-    last_sign_in_at: string,
-    confirmed_at: string,
-    last_activity_on: string,
-    email: string,
-    theme_id: number,
-    color_scheme_id: number,
-    projects_limit: number,
-    current_sign_in_at: string,
-    identities: Array<{
-        provider: string, extern_uid: string
-    }>,
-    can_create_group: boolean,
-    can_create_project: boolean,
-    two_factor_enabled: boolean,
-    external: boolean,
-    private_profile: boolean,
-    commit_email: string
-}
-
-
-export default GitlabProfile;
\ No newline at end of file
diff --git a/types/Gitlab/GitlabRelease.ts b/types/Gitlab/GitlabRelease.ts
deleted file mode 100644
index a7c68d770e4e88c7acd2f6f6eb1305329c42f61d..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabRelease.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import GitlabUser      from './GitlabUser';
-import GitlabCommit    from './GitlabCommit';
-import GitlabMilestone from './GitlabMilestone';
-
-
-interface GitlabRelease {
-    tag_name: string;
-    description: string;
-    created_at: string;
-    released_at: string;
-    author: GitlabUser;
-    commit: GitlabCommit;
-    milestones: Array<GitlabMilestone>;
-    commit_path: string;
-    tag_path: string;
-    assets: {
-        count: number; sources: Array<{
-            format: string; url: string;
-        }>; links: Array<{
-            id: number; name: string; url: string; link_type: string;
-        }>; evidence_file_path: string;
-    };
-    evidences: Array<{
-        sha: string; filepath: string; collected_at: string;
-    }>;
-}
-
-
-export default GitlabRelease; 
\ No newline at end of file
diff --git a/types/Gitlab/GitlabRepository.ts b/types/Gitlab/GitlabRepository.ts
deleted file mode 100644
index 0aa260287cc95030231761b2781a31a1b203f22b..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabRepository.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-import GitlabGroup     from './GitlabGroup';
-import GitlabNamespace from './GitlabNamespace';
-
-
-interface GitlabRepository {
-    id: number,
-    description: string,
-    name: string,
-    name_with_namespace: string,
-    path: string,
-    path_with_namespace: string,
-    created_at: string,
-    default_branch: string,
-    tag_list: Array<string>,
-    topics: Array<string>,
-    ssh_url_to_repo: string,
-    http_url_to_repo: string,
-    web_url: string,
-    readme_url: string,
-    forks_count: number,
-    avatar_url: string,
-    star_count: number,
-    last_activity_at: string,
-    namespace: GitlabNamespace,
-    _links: {
-        self: string, issues: string, merge_requests: string, repo_branches: string, labels: string, events: string, members: string, cluster_agents: string
-    },
-    packages_enabled: boolean,
-    empty_repo: boolean,
-    archived: boolean,
-    visibility: string,
-    resolve_outdated_diff_discussions: boolean,
-    container_expiration_policy: {
-        cadence: string, enabled: boolean, keep_n: number, older_than: string, name_regex: string, name_regex_keep: string, next_run_at: string
-    },
-    issues_enabled: boolean,
-    merge_requests_enabled: boolean,
-    wiki_enabled: boolean,
-    jobs_enabled: boolean,
-    snippets_enabled: boolean,
-    container_registry_enabled: boolean,
-    service_desk_enabled: boolean,
-    service_desk_address: string,
-    can_create_merge_request_in: boolean,
-    issues_access_level: string,
-    repository_access_level: string,
-    merge_requests_access_level: string,
-    forking_access_level: string,
-    wiki_access_level: string,
-    builds_access_level: string,
-    snippets_access_level: string,
-    pages_access_level: string,
-    operations_access_level: string,
-    analytics_access_level: string,
-    container_registry_access_level: string,
-    security_and_compliance_access_level: string,
-    releases_access_level: string,
-    environments_access_level: string,
-    feature_flags_access_level: string,
-    infrastructure_access_level: string,
-    monitor_access_level: string,
-    emails_disabled: boolean,
-    shared_runners_enabled: boolean,
-    lfs_enabled: boolean,
-    creator_id: number,
-    import_url: string,
-    import_type: string,
-    import_status: string,
-    import_error: string,
-    open_issues_count: number,
-    runners_token: string,
-    ci_default_git_depth: number,
-    ci_forward_deployment_enabled: boolean,
-    ci_job_token_scope_enabled: boolean,
-    ci_separated_caches: boolean,
-    ci_opt_in_jwt: boolean,
-    ci_allow_fork_pipelines_to_run_in_parent_project: boolean,
-    public_jobs: boolean,
-    build_git_strategy: string,
-    build_timeout: number,
-    auto_cancel_pending_pipelines: string,
-    ci_config_path: string,
-    shared_with_groups: Array<GitlabGroup>,
-    only_allow_merge_if_pipeline_succeeds: boolean,
-    allow_merge_on_skipped_pipeline: boolean,
-    restrict_user_defined_variables: boolean,
-    request_access_enabled: boolean,
-    only_allow_merge_if_all_discussions_are_resolved: boolean,
-    remove_source_branch_after_merge: boolean,
-    printing_merge_request_link_enabled: boolean,
-    merge_method: string,
-    squash_option: string,
-    enforce_auth_checks_on_uploads: boolean,
-    suggestion_commit_message: string,
-    merge_commit_template: string,
-    squash_commit_template: string,
-    issue_branch_template: string,
-    auto_devops_enabled: boolean,
-    auto_devops_deploy_strategy: string,
-    autoclose_referenced_issues: boolean,
-    keep_latest_artifact: boolean,
-    runner_token_expiration_interval: number,
-}
-
-
-export default GitlabRepository;
\ No newline at end of file
diff --git a/types/Gitlab/GitlabRoute.ts b/types/Gitlab/GitlabRoute.ts
deleted file mode 100644
index bdeccc68f582f5f477bd6fb9d8f3fe665680ca5d..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabRoute.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-enum GitlabRoute {
-    NOTIFICATION_SETTINGS       = '/notification_settings',
-    PROFILE_GET                 = '/user',
-    USERS_GET                   = '/users',
-    REPOSITORY_GET              = '/projects/{{id}}',
-    REPOSITORY_CREATE           = '/projects', // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
-    REPOSITORY_DELETE           = '/projects/{{id}}', // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
-    REPOSITORY_EDIT             = '/projects/{{id}}',
-    REPOSITORY_FORK             = '/projects/{{id}}/fork',
-    REPOSITORY_MEMBER_ADD       = '/projects/{{id}}/members',
-    REPOSITORY_MEMBERS_GET      = '/projects/{{id}}/members/all',
-    REPOSITORY_RELEASES_GET     = '/projects/{{id}}/releases',
-    REPOSITORY_BADGES_ADD       = '/projects/{{id}}/badges',
-    REPOSITORY_VARIABLES_ADD    = '/projects/{{id}}/variables',
-    REPOSITORY_BRANCHES_PROTECT = '/projects/{{id}}/protected_branches',
-    REPOSITORY_TREE             = '/projects/{{id}}/repository/tree',
-    REPOSITORY_FILE             = '/projects/{{id}}/repository/files/{{filePath}}',
-    REPOSITORY_PIPELINES        = '/projects/{{id}}/pipelines',
-}
-
-
-export default GitlabRoute;
\ No newline at end of file
diff --git a/types/Gitlab/GitlabToken.ts b/types/Gitlab/GitlabToken.ts
deleted file mode 100644
index c8c647e6285cf626b155d7ff93beb0dd2c7f9d52..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabToken.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-interface GitlabToken {
-    access_token: string;
-    token_type: string;
-    expires_in: number;
-    refresh_token: string;
-    scope: string;
-    created_at: number;
-}
-
-
-export default GitlabToken;
\ No newline at end of file
diff --git a/types/Gitlab/GitlabTreeFile.ts b/types/Gitlab/GitlabTreeFile.ts
deleted file mode 100644
index b2cf67ecb1d636838ff2e48cbc6ce62e11248476..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabTreeFile.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import GitlabTreeFileType from './GitlabTreeFileType';
-
-
-interface GitlabTreeFile {
-    id: number,
-    name: string,
-    type: GitlabTreeFileType,
-    path: string,
-    mode: string
-}
-
-
-export default GitlabTreeFile;
\ No newline at end of file
diff --git a/types/Gitlab/GitlabTreeFileType.ts b/types/Gitlab/GitlabTreeFileType.ts
deleted file mode 100644
index eead9b931715ec73fa158513775419dfb14ee538..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabTreeFileType.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-enum GitlabTreeFileType {
-    TREE   = 'tree',
-    BLOB   = 'blob',
-    COMMIT = 'commit'
-}
-
-
-export default GitlabTreeFileType;
diff --git a/types/Gitlab/GitlabUser.ts b/types/Gitlab/GitlabUser.ts
deleted file mode 100644
index bbb759264764020b1dd80cca050392371b8e87b7..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabUser.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-interface GitlabUser {
-    id: number,
-    username: string,
-    name: string,
-    state: string,
-    avatar_url: string,
-    web_url: string,
-}
-
-
-export default GitlabUser;
\ No newline at end of file
diff --git a/types/Gitlab/GitlabVisibility.ts b/types/Gitlab/GitlabVisibility.ts
deleted file mode 100644
index 842ff168e274cb6cfb2a39ef7a952cdb5248c1b9..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabVisibility.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-enum GitlabVisibility {
-    PUBLIC   = 'public',
-    INTERNAL = 'internal',
-    PRIVATE  = 'private'
-}
-
-
-export default GitlabVisibility;
diff --git a/types/Icon.ts b/types/Icon.ts
deleted file mode 100644
index 33ee07279853d172f2c975a01f6299b438449175..0000000000000000000000000000000000000000
--- a/types/Icon.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-const Icon = {
-    CAT_INFO : '▶️',
-    INFO     : 'ℹ️',
-    ERROR    : '⛔️',
-    SUCCESS  : '✅',
-    FAILURE  : '❌',
-    VOMIT    : '🤮',
-    YUCK     : '🤢',
-    WELL_DONE: '👍',
-    NULL     : '',
-    NONE     : '',
-    BADMINTON: '🏸'
-} as { [index: string]: string };
-
-
-export default Icon;
\ No newline at end of file