diff --git a/common/home/neovim/langs/web.nix b/common/home/neovim/langs/web.nix
index 24d9c04c..d983f53e 100644
--- a/common/home/neovim/langs/web.nix
+++ b/common/home/neovim/langs/web.nix
@@ -27,18 +27,18 @@ in
           # lua
           ''
             vim.api.nvim_create_autocmd('FileType', {
-               pattern = { 'javascript', 'typescript', 'css', 'scss' },
-               command = 'setlocal ts=4 sw=4 sts=0 expandtab',
+                pattern = { 'javascript', 'typescript', 'css', 'scss' },
+                command = 'setlocal ts=4 sw=4 sts=0 expandtab',
             });
 
             vim.api.nvim_create_autocmd('FileType', {
-               pattern = 'html',
-               command = 'setlocal ts=2 sw=2 expandtab',
+                pattern = 'html',
+                command = 'setlocal ts=2 sw=2 expandtab',
             });
 
             vim.api.nvim_create_autocmd('FileType', {
-               pattern = 'scss',
-               command = 'setlocal iskeyword+=@-@',
+                pattern = 'scss',
+                command = 'setlocal iskeyword+=@-@',
             });
 
             local lsp = require('lspconfig');
@@ -66,6 +66,41 @@ in
                         command = 'EslintFixAll',
                     });
                 end,
+
+                settings = {
+                    validate = 'on',
+                    packageManager = 'npm',
+                    useESLintClass = true,
+                    useFlatConfig = true,
+                    experimental = {
+                        useFlatConfig = true,
+                    },
+                    codeAction = {
+                        disableRuleComment = {
+                            enable = true,
+                            location = 'separateLine'
+                        },
+                        showDocumentation = {
+                            enable = true,
+                        },
+                    },
+                    codeActionOnSave = {
+                        mode = 'all',
+                        rules = {},
+                    },
+                    format = true,
+                    quiet = false,
+                    onIgnoredFiles = 'off',
+                    rulesCustomizations = {},
+                    run = 'onType',
+                    problems = {
+                        shortenToSingleLine = false,
+                    },
+                    nodePath = "",
+                    workingDirectory = {
+                        mode = 'location',
+                    },
+                },
             });
 
             lsp.cssls.setup({
diff --git a/modules/ags/config/eslint.config.js b/modules/ags/config/eslint.config.js
index fb088f0e..34662af8 100644
--- a/modules/ags/config/eslint.config.js
+++ b/modules/ags/config/eslint.config.js
@@ -1,461 +1,454 @@
 // TODO: switch to typescript https://github.com/eslint/eslint/pull/18134
 
 import eslint from '@eslint/js';
-
-import tseslint from 'typescript-eslint';
-import tsPlugin from '@typescript-eslint/eslint-plugin';
-
-import stylistic from '@stylistic/eslint-plugin';
-// import stylisticRules from '@stylistic/eslint-plugin/rule-options';
-
 import jsdoc from 'eslint-plugin-jsdoc';
+import stylistic from '@stylistic/eslint-plugin';
+import tseslint from 'typescript-eslint';
 
 
-export default tseslint.config(
-    // @ts-expect-error this works
-    eslint.configs.recommended,
-    jsdoc.configs['flat/recommended-typescript'],
+export default tseslint.config({
+    // @ts-expect-error this should work
+    files: ['**/*.js', '**/*.ts'],
+    ignores: ['node_modules/**', 'types/**'],
 
-    { ignores: ['js'] },
+    extends: [
+        eslint.configs.recommended,
+        jsdoc.configs['flat/recommended-typescript'],
+        stylistic.configs['recommended-flat'],
+        ...tseslint.configs.recommended,
+        ...tseslint.configs.stylistic,
+    ],
 
-    {
-        plugins: {
-            jsdoc,
-            '@stylistic': stylistic, // as typeof stylisticRules,
-            '@typescript-eslint': tsPlugin,
-        },
+    rules: {
+        // JSDoc settings
+        'jsdoc/tag-lines': ['warn', 'any', { startLines: 1 }],
+        'jsdoc/check-line-alignment': ['warn', 'always', {
+            tags: ['param', 'arg', 'argument', 'property', 'prop'],
+        }],
+        'jsdoc/no-types': 'off',
 
-        rules: {
-            // JSDoc settings
-            'jsdoc/tag-lines': ['warn', 'any', { startLines: 1 }],
-            'jsdoc/check-line-alignment': ['warn', 'always', {
-                tags: ['param', 'arg', 'argument', 'property', 'prop'],
-            }],
+        // Newer settings
+        '@typescript-eslint/no-extraneous-class': ['off'],
+        '@typescript-eslint/no-implied-eval': ['off'],
+        'class-methods-use-this': 'off',
+        '@stylistic/no-multiple-empty-lines': 'off',
 
-            // Newer settings
-            '@typescript-eslint/no-extraneous-class': ['off'],
-            '@typescript-eslint/no-implied-eval': ['off'],
+        // Pre-flat config
+        '@typescript-eslint/no-unused-vars': [
+            'error',
+            {
+                args: 'all',
+                argsIgnorePattern: '^_',
+                caughtErrors: 'all',
+                caughtErrorsIgnorePattern: '^_',
+                destructuredArrayIgnorePattern: '^_',
+                varsIgnorePattern: '^_',
+                ignoreRestSiblings: true,
+            },
+        ],
 
-            // Pre-flat config
-            '@typescript-eslint/no-unused-vars': [
-                'error',
-                {
-                    args: 'all',
-                    argsIgnorePattern: '^_',
-                    caughtErrors: 'all',
-                    caughtErrorsIgnorePattern: '^_',
-                    destructuredArrayIgnorePattern: '^_',
-                    varsIgnorePattern: '^_',
-                    ignoreRestSiblings: true,
-                },
-            ],
-
-            'array-callback-return': [
-                'error',
-                {
-                    allowImplicit: true,
-                    checkForEach: true,
-                },
-            ],
-            'no-constructor-return': [
-                'error',
-            ],
-            'no-unreachable-loop': [
-                'error',
-                {
-                    ignore: [
-                        'ForInStatement',
-                        'ForOfStatement',
-                    ],
-                },
-            ],
-            'no-use-before-define': [
-                'error',
-                {
-                    functions: false,
-                },
-            ],
-            'block-scoped-var': [
-                'error',
-            ],
-            'class-methods-use-this': [
-                'error',
-            ],
-            'curly': [
-                'warn',
-            ],
-            'default-case-last': [
-                'warn',
-            ],
-            'default-param-last': [
-                'error',
-            ],
-            'eqeqeq': [
-                'error',
-                'smart',
-            ],
-            'func-names': [
-                'warn',
-                'never',
-            ],
-            'func-style': [
-                'warn',
-                'expression',
-            ],
-            'logical-assignment-operators': [
-                'warn',
-                'always',
-            ],
-            'no-array-constructor': [
-                'error',
-            ],
-            'no-empty-function': [
-                'warn',
-            ],
-            'no-empty-static-block': [
-                'warn',
-            ],
-            'no-extend-native': [
-                'error',
-            ],
-            'no-extra-bind': [
-                'warn',
-            ],
-            'no-implicit-coercion': [
-                'warn',
-            ],
-            'no-iterator': [
-                'error',
-            ],
-            'no-labels': [
-                'error',
-            ],
-            'no-lone-blocks': [
-                'error',
-            ],
-            'no-lonely-if': [
-                'error',
-            ],
-            'no-loop-func': [
-                'error',
-            ],
-            'no-magic-numbers': [
-                'error',
-                {
-                    ignore: [
-                        -1,
-                        0.1,
-                        0,
-                        1,
-                        2,
-                        3,
-                        4,
-                        5,
-                        10,
-                        12,
-                        33,
-                        66,
-                        100,
-                        255,
-                        360,
-                        450,
-                        500,
-                        1000,
-                    ],
-                    ignoreDefaultValues: true,
-                    ignoreClassFieldInitialValues: true,
-                },
-            ],
-            'no-multi-assign': [
-                'error',
-            ],
-            'no-new-wrappers': [
-                'error',
-            ],
-            'no-object-constructor': [
-                'error',
-            ],
-            'no-proto': [
-                'error',
-            ],
-            'no-return-assign': [
-                'error',
-            ],
-            'no-sequences': [
-                'error',
-            ],
-            'no-shadow': [
-                'error',
-                {
-                    builtinGlobals: true,
-                    allow: [
-                        'Window',
-                    ],
-                },
-            ],
-            'no-undef-init': [
-                'warn',
-            ],
-            'no-undefined': [
-                'error',
-            ],
-            'no-useless-constructor': [
-                'warn',
-            ],
-            'no-useless-escape': [
-                'off',
-            ],
-            'no-useless-return': [
-                'error',
-            ],
-            'no-var': [
-                'error',
-            ],
-            'no-void': [
-                'off',
-            ],
-            'no-with': [
-                'error',
-            ],
-            'object-shorthand': [
-                'error',
-                'always',
-            ],
-            'one-var': [
-                'error',
-                'never',
-            ],
-            'operator-assignment': [
-                'warn',
-                'always',
-            ],
-            'prefer-arrow-callback': [
-                'error',
-            ],
-            'prefer-const': [
-                'error',
-            ],
-            'prefer-object-has-own': [
-                'error',
-            ],
-            'prefer-regex-literals': [
-                'error',
-            ],
-            'prefer-template': [
-                'warn',
-            ],
-            'no-prototype-builtins': 'off',
-            '@typescript-eslint/no-var-requires': [
-                'off',
-            ],
-            '@stylistic/array-bracket-newline': [
-                'warn',
-                'consistent',
-            ],
-            '@stylistic/array-bracket-spacing': [
-                'warn',
-                'never',
-            ],
-            '@stylistic/arrow-parens': [
-                'warn',
-                'always',
-            ],
-            '@stylistic/brace-style': [
-                'warn',
-                'stroustrup',
-            ],
-            '@stylistic/comma-dangle': [
-                'warn',
-                'always-multiline',
-            ],
-            '@stylistic/comma-spacing': [
-                'warn',
-                {
-                    before: false,
-                    after: true,
-                },
-            ],
-            '@stylistic/comma-style': [
-                'error',
-                'last',
-            ],
-            '@stylistic/dot-location': [
-                'error',
-                'property',
-            ],
-            '@stylistic/function-call-argument-newline': [
-                'warn',
-                'consistent',
-            ],
-            '@stylistic/function-paren-newline': [
-                'warn',
-                'consistent',
-            ],
-            '@stylistic/indent': [
-                'warn',
-                4,
-                {
-                    SwitchCase: 1,
-                    ignoreComments: true,
-                    ignoredNodes: ['TemplateLiteral > *'],
-                },
-            ],
-            '@stylistic/key-spacing': [
-                'warn',
-                {
-                    beforeColon: false,
-                    afterColon: true,
-                },
-            ],
-            '@stylistic/keyword-spacing': [
-                'warn',
-                {
-                    before: true,
-                },
-            ],
-            '@stylistic/linebreak-style': [
-                'error',
-                'unix',
-            ],
-            '@stylistic/lines-between-class-members': [
-                'warn',
-                'always',
-                {
-                    exceptAfterSingleLine: true,
-                },
-            ],
-            '@stylistic/max-len': [
-                'warn',
-                {
-                    code: 105,
-                    ignoreComments: true,
-                    ignoreTrailingComments: true,
-                    ignoreUrls: true,
-                },
-            ],
-            '@stylistic/multiline-ternary': [
-                'warn',
-                'always-multiline',
-            ],
-            '@stylistic/new-parens': [
-                'error',
-            ],
-            '@stylistic/no-mixed-operators': [
-                'warn',
-            ],
-            '@stylistic/no-mixed-spaces-and-tabs': [
-                'error',
-            ],
-            '@stylistic/no-multi-spaces': [
-                'error',
-            ],
-            '@stylistic/no-tabs': [
-                'error',
-            ],
-            '@stylistic/no-trailing-spaces': [
-                'error',
-            ],
-            '@stylistic/no-whitespace-before-property': [
-                'warn',
-            ],
-            '@stylistic/nonblock-statement-body-position': [
-                'error',
-                'below',
-            ],
-            '@stylistic/object-curly-newline': [
-                'warn',
-                {
-                    consistent: true,
-                },
-            ],
-            '@stylistic/object-curly-spacing': [
-                'warn',
-                'always',
-            ],
-            '@stylistic/operator-linebreak': [
-                'warn',
-                'after',
-            ],
-            '@stylistic/padded-blocks': [
-                'error',
-                'never',
-            ],
-            '@stylistic/padding-line-between-statements': [
-                'warn',
-                {
-                    blankLine: 'always',
-                    prev: '*',
-                    next: 'return',
-                },
-                {
-                    blankLine: 'always',
-                    prev: [
-                        'const',
-                        'let',
-                        'var',
-                    ],
-                    next: '*',
-                },
-                {
-                    blankLine: 'any',
-                    prev: [
-                        'const',
-                        'let',
-                        'var',
-                    ],
-                    next: [
-                        'const',
-                        'let',
-                        'var',
-                    ],
-                },
-                {
-                    blankLine: 'always',
-                    prev: [
-                        'case',
-                        'default',
-                    ],
-                    next: '*',
-                },
-            ],
-            '@stylistic/quote-props': [
-                'error',
-                'consistent-as-needed',
-            ],
-            '@stylistic/quotes': [
-                'error',
-                'single',
-                {
-                    avoidEscape: true,
-                },
-            ],
-            '@stylistic/semi': [
-                'error',
-                'always',
-            ],
-            '@stylistic/semi-spacing': [
-                'warn',
-            ],
-            '@stylistic/space-before-blocks': [
-                'warn',
-            ],
-            '@stylistic/space-before-function-paren': [
-                'warn',
-                'never',
-            ],
-            '@stylistic/space-infix-ops': [
-                'warn',
-            ],
-            '@stylistic/spaced-comment': [
-                'warn',
-                'always',
-            ],
-            '@stylistic/switch-colon-spacing': [
-                'warn',
-            ],
-            '@stylistic/wrap-regex': [
-                'warn',
-            ],
-        },
+        'array-callback-return': [
+            'error',
+            {
+                allowImplicit: true,
+                checkForEach: true,
+            },
+        ],
+        'no-constructor-return': [
+            'error',
+        ],
+        'no-unreachable-loop': [
+            'error',
+            {
+                ignore: [
+                    'ForInStatement',
+                    'ForOfStatement',
+                ],
+            },
+        ],
+        'no-use-before-define': [
+            'error',
+            {
+                functions: false,
+            },
+        ],
+        'block-scoped-var': [
+            'error',
+        ],
+        'curly': [
+            'warn',
+        ],
+        'default-case-last': [
+            'warn',
+        ],
+        'default-param-last': [
+            'error',
+        ],
+        'eqeqeq': [
+            'error',
+            'smart',
+        ],
+        'func-names': [
+            'warn',
+            'never',
+        ],
+        'func-style': [
+            'warn',
+            'expression',
+        ],
+        'logical-assignment-operators': [
+            'warn',
+            'always',
+        ],
+        'no-array-constructor': [
+            'error',
+        ],
+        'no-empty-function': [
+            'warn',
+        ],
+        'no-empty-static-block': [
+            'warn',
+        ],
+        'no-extend-native': [
+            'error',
+        ],
+        'no-extra-bind': [
+            'warn',
+        ],
+        'no-implicit-coercion': [
+            'warn',
+        ],
+        'no-iterator': [
+            'error',
+        ],
+        'no-labels': [
+            'error',
+        ],
+        'no-lone-blocks': [
+            'error',
+        ],
+        'no-lonely-if': [
+            'error',
+        ],
+        'no-loop-func': [
+            'error',
+        ],
+        'no-magic-numbers': [
+            'error',
+            {
+                ignore: [
+                    -1,
+                    0.1,
+                    0,
+                    1,
+                    2,
+                    3,
+                    4,
+                    5,
+                    10,
+                    12,
+                    33,
+                    66,
+                    100,
+                    255,
+                    360,
+                    450,
+                    500,
+                    1000,
+                ],
+                ignoreDefaultValues: true,
+                ignoreClassFieldInitialValues: true,
+            },
+        ],
+        'no-multi-assign': [
+            'error',
+        ],
+        'no-new-wrappers': [
+            'error',
+        ],
+        'no-object-constructor': [
+            'error',
+        ],
+        'no-proto': [
+            'error',
+        ],
+        'no-return-assign': [
+            'error',
+        ],
+        'no-sequences': [
+            'error',
+        ],
+        'no-shadow': [
+            'error',
+            {
+                builtinGlobals: true,
+                allow: [
+                    'Window',
+                ],
+            },
+        ],
+        'no-undef-init': [
+            'warn',
+        ],
+        'no-undefined': [
+            'error',
+        ],
+        'no-useless-constructor': [
+            'warn',
+        ],
+        'no-useless-escape': [
+            'off',
+        ],
+        'no-useless-return': [
+            'error',
+        ],
+        'no-var': [
+            'error',
+        ],
+        'no-void': [
+            'off',
+        ],
+        'no-with': [
+            'error',
+        ],
+        'object-shorthand': [
+            'error',
+            'always',
+        ],
+        'one-var': [
+            'error',
+            'never',
+        ],
+        'operator-assignment': [
+            'warn',
+            'always',
+        ],
+        'prefer-arrow-callback': [
+            'error',
+        ],
+        'prefer-const': [
+            'error',
+        ],
+        'prefer-object-has-own': [
+            'error',
+        ],
+        'prefer-regex-literals': [
+            'error',
+        ],
+        'prefer-template': [
+            'warn',
+        ],
+        'no-prototype-builtins': 'off',
+        '@typescript-eslint/no-var-requires': [
+            'off',
+        ],
+        '@stylistic/array-bracket-newline': [
+            'warn',
+            'consistent',
+        ],
+        '@stylistic/array-bracket-spacing': [
+            'warn',
+            'never',
+        ],
+        '@stylistic/arrow-parens': [
+            'warn',
+            'always',
+        ],
+        '@stylistic/brace-style': [
+            'warn',
+            'stroustrup',
+        ],
+        '@stylistic/comma-dangle': [
+            'warn',
+            'always-multiline',
+        ],
+        '@stylistic/comma-spacing': [
+            'warn',
+            {
+                before: false,
+                after: true,
+            },
+        ],
+        '@stylistic/comma-style': [
+            'error',
+            'last',
+        ],
+        '@stylistic/dot-location': [
+            'error',
+            'property',
+        ],
+        '@stylistic/function-call-argument-newline': [
+            'warn',
+            'consistent',
+        ],
+        '@stylistic/function-paren-newline': [
+            'warn',
+            'consistent',
+        ],
+        '@stylistic/indent': [
+            'warn',
+            4,
+            {
+                SwitchCase: 1,
+                ignoreComments: true,
+                ignoredNodes: ['TemplateLiteral > *'],
+            },
+        ],
+        '@stylistic/key-spacing': [
+            'warn',
+            {
+                beforeColon: false,
+                afterColon: true,
+            },
+        ],
+        '@stylistic/keyword-spacing': [
+            'warn',
+            {
+                before: true,
+            },
+        ],
+        '@stylistic/linebreak-style': [
+            'error',
+            'unix',
+        ],
+        '@stylistic/lines-between-class-members': [
+            'warn',
+            'always',
+            {
+                exceptAfterSingleLine: true,
+            },
+        ],
+        '@stylistic/max-len': [
+            'warn',
+            {
+                code: 105,
+                ignoreComments: true,
+                ignoreTrailingComments: true,
+                ignoreUrls: true,
+            },
+        ],
+        '@stylistic/multiline-ternary': [
+            'warn',
+            'always-multiline',
+        ],
+        '@stylistic/new-parens': [
+            'error',
+        ],
+        '@stylistic/no-mixed-operators': [
+            'warn',
+        ],
+        '@stylistic/no-mixed-spaces-and-tabs': [
+            'error',
+        ],
+        '@stylistic/no-multi-spaces': [
+            'error',
+        ],
+        '@stylistic/no-tabs': [
+            'error',
+        ],
+        '@stylistic/no-trailing-spaces': [
+            'error',
+        ],
+        '@stylistic/no-whitespace-before-property': [
+            'warn',
+        ],
+        '@stylistic/nonblock-statement-body-position': [
+            'error',
+            'below',
+        ],
+        '@stylistic/object-curly-newline': [
+            'warn',
+            {
+                consistent: true,
+            },
+        ],
+        '@stylistic/object-curly-spacing': [
+            'warn',
+            'always',
+        ],
+        '@stylistic/operator-linebreak': [
+            'warn',
+            'after',
+        ],
+        '@stylistic/padded-blocks': [
+            'error',
+            'never',
+        ],
+        '@stylistic/padding-line-between-statements': [
+            'warn',
+            {
+                blankLine: 'always',
+                prev: '*',
+                next: 'return',
+            },
+            {
+                blankLine: 'always',
+                prev: [
+                    'const',
+                    'let',
+                    'var',
+                ],
+                next: '*',
+            },
+            {
+                blankLine: 'any',
+                prev: [
+                    'const',
+                    'let',
+                    'var',
+                ],
+                next: [
+                    'const',
+                    'let',
+                    'var',
+                ],
+            },
+            {
+                blankLine: 'always',
+                prev: [
+                    'case',
+                    'default',
+                ],
+                next: '*',
+            },
+        ],
+        '@stylistic/quote-props': [
+            'error',
+            'consistent-as-needed',
+        ],
+        '@stylistic/quotes': [
+            'error',
+            'single',
+            {
+                avoidEscape: true,
+            },
+        ],
+        '@stylistic/semi': [
+            'error',
+            'always',
+        ],
+        '@stylistic/semi-spacing': [
+            'warn',
+        ],
+        '@stylistic/space-before-blocks': [
+            'warn',
+        ],
+        '@stylistic/space-before-function-paren': [
+            'warn',
+            'never',
+        ],
+        '@stylistic/space-infix-ops': [
+            'warn',
+        ],
+        '@stylistic/spaced-comment': [
+            'warn',
+            'always',
+        ],
+        '@stylistic/switch-colon-spacing': [
+            'warn',
+        ],
+        '@stylistic/wrap-regex': [
+            'warn',
+        ],
     },
-);
+});
diff --git a/modules/ags/config/global-types.d.ts b/modules/ags/config/global-types.d.ts
index 3f04e345..52855870 100644
--- a/modules/ags/config/global-types.d.ts
+++ b/modules/ags/config/global-types.d.ts
@@ -5,137 +5,6 @@ import { Variable as Var } from 'types/variable';
 import { Widget as agsWidget } from 'types/widgets/widget';
 export type AgsWidget = agsWidget<unknown> & Widget;
 
-// For ./ts/applauncher/main.ts
-import { Application } from 'types/service/applications.ts';
-import { CursorBoxProps } from 'ts/misc/cursorbox';
-export type AgsAppItem = AgsEventBox<Widget, { app: Application }
-& CursorBoxProps<Widget, unknown>>;
-
-// For ./ts/bar/hovers/keyboard.ts
-export type Keyboard = {
-    address: string;
-    name: string;
-    rules: string;
-    model: string;
-    layout: string;
-    variant: string;
-    options: string;
-    active_keymap: string;
-    main: boolean;
-};
-
-// For ./ts/bar/items/workspaces.ts
-// TODO: improve type
-export type Workspace = AgsRevealer<unknown & Widget, unknown & { id: number }>;
-
-// For ./ts/bar/fullscreen.ts
-export type DefaultProps = RevealerProps<CenterBoxGeneric>;
-
-// For ./ts/media-player/gesture.ts
-export type Gesture = {
-    attribute?: object
-    setup?(self: OverlayGeneric): void
-    props?: OverlayProps<unknown & Widget, unknown>
-};
-
-// For ./ts/media-player/mpris.ts
-type PlayerDragProps = unknown & { dragging: boolean };
-export type PlayerDrag = AgsCenterBox<
-unknown & Widget, unknown & Widget, unknown & Widget, unknown & PlayerDragProps
->;
-type Colors = {
-    imageAccent: string;
-    buttonAccent: string;
-    buttonText: string;
-    hoverAccent: string;
-};
-
-// For ./ts/media-player
-export type PlayerBoxProps = {
-    bgStyle: string,
-    player: MprisPlayer,
-};
-export type PlayerBox = AgsCenterBox<
-unknown & Widget, unknown & Widget, unknown & Widget, PlayerBoxProps
->;
-export type PlayerOverlay = AgsOverlay<AgsWidget, {
-    players: Map;
-    setup: boolean;
-    dragging: boolean;
-    includesWidget(playerW: PlayerBox): PlayerBox;
-    showTopOnly(): void;
-    moveToTop(player: PlayerBox): void;
-}>;
-export type PlayerButtonType = {
-    player: MprisPlayer
-    colors: Var<Colors>
-    children: StackProps['children']
-    onClick: string
-    prop: string
-};
-
-// For ./ts/notifications/gesture.js
-type NotifGestureProps = {
-    dragging: boolean;
-    hovered: boolean
-    ready: boolean
-    id: number;
-    slideAway(side: 'Left' | 'Right'): void;
-};
-export type NotifGesture = AgsEventBox<BoxGeneric, NotifGestureProps>;
-
-// For ./ts/osd/ctor.ts
-export type OSDStack = AgsStack<unknown & Widget, {
-    popup(osd: string): void,
-}>;
-export type ConnectFunc = (self?: ProgressBarGeneric) => void;
-export type OSD = {
-    name: string;
-    icon: IconPropsGeneric['icon'];
-    info: {
-        mod: GObject.Object;
-        signal?: string | string[];
-        logic?(self: ProgressBarGeneric): void;
-        widget?: AgsWidget;
-    }
-};
-
-// For ./ts/on-screen-keyboard
-export type OskWindow = Window<BoxGeneric, {
-    startY: null | number;
-    setVisible: (state: boolean) => void;
-    killGestureSigs: () => void;
-    setSlideUp: () => void;
-    setSlideDown: () => void;
-}>;
-
-// For CursorBox
-import { CursorBox, CursorBoxProps } from 'ts/misc/cursorbox';
-export type CursorBox = CursorBox;
-export type CursorBoxProps = CursorBoxProps;
-
-// For PopupWindow
-export type HyprTransition = 'slide' | 'slide top' | 'slide bottom' | 'slide left' |
-'slide right' | 'popin' | 'fade';
-export type CloseType = 'none' | 'stay' | 'released' | 'clicked';
-import { PopupWindow } from 'ts/misc/popup';
-export type PopupWindow = PopupWindow;
-
-// For ./ts/quick-settings
-import { BluetoothDevice as BTDev } from 'types/service/bluetooth.ts';
-export type APType = {
-    bssid: string
-    address: string
-    lastSeen: number
-    ssid: string
-    active: boolean
-    strength: number
-    iconName: string
-};
-export type APBox = AgsBox<unknown & Widget, { ap: Var<APType> }>;
-export type DeviceBox = AgsBox<unknown & Widget, { dev: BTDev }>;
-
-
 // Generic widgets
 import AgsBox from 'types/widgets/box.ts';
 export type BoxGeneric = AgsBox<unknown & Widget, unknown>;
@@ -168,10 +37,141 @@ import AgsRevealer, { RevealerProps } from 'types/widgets/revealer';
 export type RevealerGeneric = AgsRevealer<unknown & Widget, unknown>;
 
 import AgsStack, { StackProps } from 'types/widgets/stack';
-export type StackGeneric = AgsStack<{ [name: string]: Widget; }, unknown>;
+export type StackGeneric = AgsStack<Record<string, Widget>, unknown>;
 
 import AgsScrollable from 'types/widgets/scrollable';
 export type ScrollableGeneric = AgsScrollable<unkown & Widget, unknown>;
 
 import AgsWindow from 'types/widgets/window';
 export type WindowGeneric = AgsWindow<unknown & Widget, unknown>;
+
+
+// For ./ts/applauncher/main.ts
+import { Application } from 'types/service/applications.ts';
+import { CursorBoxProps } from 'ts/misc/cursorbox';
+export type AgsAppItem = AgsEventBox<Widget, { app: Application }
+  & CursorBoxProps<Widget, unknown>>;
+
+// For ./ts/bar/hovers/keyboard.ts
+export interface Keyboard {
+    address: string
+    name: string
+    rules: string
+    model: string
+    layout: string
+    variant: string
+    options: string
+    active_keymap: string
+    main: boolean
+}
+
+// For ./ts/bar/items/workspaces.ts
+// TODO: improve type
+export type Workspace = AgsRevealer<unknown & Widget, unknown & { id: number }>;
+
+// For ./ts/bar/fullscreen.ts
+export type DefaultProps = RevealerProps<CenterBoxGeneric>;
+
+// For ./ts/media-player/gesture.ts
+export interface Gesture {
+    attribute?: object
+    setup?(self: OverlayGeneric): void
+    props?: OverlayProps<unknown & Widget, unknown>
+}
+
+// For ./ts/media-player/mpris.ts
+type PlayerDragProps = unknown & { dragging: boolean };
+export type PlayerDrag = AgsCenterBox<
+unknown & Widget, unknown & Widget, unknown & Widget, unknown & PlayerDragProps
+>;
+interface Colors {
+    imageAccent: string
+    buttonAccent: string
+    buttonText: string
+    hoverAccent: string
+}
+
+// For ./ts/media-player
+export interface PlayerBoxProps {
+    bgStyle: string
+    player: MprisPlayer
+}
+export type PlayerBox = AgsCenterBox<
+unknown & Widget, unknown & Widget, unknown & Widget, PlayerBoxProps
+>;
+export type PlayerOverlay = AgsOverlay<AgsWidget, {
+    players: Map
+    setup: boolean
+    dragging: boolean
+    includesWidget(playerW: PlayerBox): PlayerBox
+    showTopOnly(): void
+    moveToTop(player: PlayerBox): void
+}>;
+export interface PlayerButtonType {
+    player: MprisPlayer
+    colors: Var<Colors>
+    children: StackProps['children']
+    onClick: string
+    prop: string
+}
+
+// For ./ts/notifications/gesture.js
+interface NotifGestureProps {
+    dragging: boolean
+    hovered: boolean
+    ready: boolean
+    id: number
+    slideAway(side: 'Left' | 'Right'): void
+}
+export type NotifGesture = AgsEventBox<BoxGeneric, NotifGestureProps>;
+
+// For ./ts/osd/ctor.ts
+export type OSDStack = AgsStack<unknown & Widget, {
+    popup(osd: string): void
+}>;
+export type ConnectFunc = (self?: ProgressBarGeneric) => void;
+export interface OSD {
+    name: string
+    icon: IconPropsGeneric['icon']
+    info: {
+        mod: GObject.Object
+        signal?: string | string[]
+        logic?(self: ProgressBarGeneric): void
+        widget?: AgsWidget
+    }
+}
+
+// For ./ts/on-screen-keyboard
+export type OskWindow = Window<BoxGeneric, {
+    startY: null | number
+    setVisible: (state: boolean) => void
+    killGestureSigs: () => void
+    setSlideUp: () => void
+    setSlideDown: () => void
+}>;
+
+// For CursorBox
+import { CursorBox, CursorBoxProps } from 'ts/misc/cursorbox';
+export type CursorBox = CursorBox;
+export type CursorBoxProps = CursorBoxProps;
+
+// For PopupWindow
+export type HyprTransition = 'slide' | 'slide top' | 'slide bottom' | 'slide left' |
+  'slide right' | 'popin' | 'fade';
+export type CloseType = 'none' | 'stay' | 'released' | 'clicked';
+import { PopupWindow } from 'ts/misc/popup';
+export type PopupWindow = PopupWindow;
+
+// For ./ts/quick-settings
+import { BluetoothDevice as BTDev } from 'types/service/bluetooth.ts';
+export interface APType {
+    bssid: string
+    address: string
+    lastSeen: number
+    ssid: string
+    active: boolean
+    strength: number
+    iconName: string
+}
+export type APBox = AgsBox<unknown & Widget, { ap: Var<APType> }>;
+export type DeviceBox = AgsBox<unknown & Widget, { dev: BTDev }>;
diff --git a/modules/ags/config/js/utils.js b/modules/ags/config/js/utils.js
index c776f621..ed83a97a 100644
--- a/modules/ags/config/js/utils.js
+++ b/modules/ags/config/js/utils.js
@@ -1,7 +1,9 @@
 const { execAsync, monitorFile } = Utils;
 
 
-/** @param {string} host */
+/**
+ * @param {string} host the name of the machine/user who's running ags
+ */
 const watchAndCompileSass = (host) => {
     const reloadCss = () => {
         const scss = `${App.configDir}/scss/${host}.scss`;
@@ -20,7 +22,10 @@ const watchAndCompileSass = (host) => {
     reloadCss();
 };
 
-/** @param {string} host */
+/**
+ * @param {string} host the name of the machine/user who's running ags
+ * @returns the config
+ */
 export const transpileTypeScript = async(host) => {
     const outPath = `/tmp/ags-${host}/index.js`;
 
diff --git a/modules/ags/config/package-lock.json b/modules/ags/config/package-lock.json
index ade0ce50..95d56699 100644
--- a/modules/ags/config/package-lock.json
+++ b/modules/ags/config/package-lock.json
@@ -8,14 +8,14 @@
                 "fzf": "0.5.2"
             },
             "devDependencies": {
-                "@eslint/js": "9.7.0",
-                "@stylistic/eslint-plugin": "2.3.0",
+                "@eslint/js": "9.8.0",
+                "@stylistic/eslint-plugin": "2.6.1",
                 "@types/eslint__js": "8.42.3",
-                "@types/node": "20.14.11",
-                "eslint": "9.7.0",
-                "eslint-plugin-jsdoc": "48.7.0",
-                "typescript": "5.5.3",
-                "typescript-eslint": "7.16.1"
+                "@types/node": "22.0.2",
+                "eslint": "9.8.0",
+                "eslint-plugin-jsdoc": "48.10.2",
+                "typescript": "5.5.4",
+                "typescript-eslint": "8.0.0"
             }
         },
         "node_modules/@es-joy/jsdoccomment": {
@@ -73,9 +73,9 @@
             }
         },
         "node_modules/@eslint/config-array": {
-            "version": "0.17.0",
-            "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.0.tgz",
-            "integrity": "sha512-A68TBu6/1mHHuc5YJL0U0VVeGNiklLAL6rRmhTCP2B5XjWLMnrX+HkO+IAXyHvks5cyyY1jjK5ITPQ1HGS2EVA==",
+            "version": "0.17.1",
+            "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.1.tgz",
+            "integrity": "sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==",
             "dev": true,
             "license": "Apache-2.0",
             "dependencies": {
@@ -160,9 +160,9 @@
             }
         },
         "node_modules/@eslint/js": {
-            "version": "9.7.0",
-            "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.7.0.tgz",
-            "integrity": "sha512-ChuWDQenef8OSFnvuxv0TCVxEwmu3+hPNKvM9B34qpM0rDRbjL8t5QkQeHHeAfsKQjuH9wS82WeCi1J/owatng==",
+            "version": "9.8.0",
+            "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.8.0.tgz",
+            "integrity": "sha512-MfluB7EUfxXtv3i/++oh89uzAr4PDI4nn201hsp+qaXqsjAWzinlZEHEfPgAX4doIlKvPG/i0A9dpKxOLII8yA==",
             "dev": true,
             "license": "MIT",
             "engines": {
@@ -259,17 +259,17 @@
             }
         },
         "node_modules/@stylistic/eslint-plugin": {
-            "version": "2.3.0",
-            "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-2.3.0.tgz",
-            "integrity": "sha512-rtiz6u5gRyyEZp36FcF1/gHJbsbT3qAgXZ1qkad6Nr/xJ9wrSJkiSFFQhpYVTIZ7FJNRJurEcumZDCwN9dEI4g==",
+            "version": "2.6.1",
+            "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-2.6.1.tgz",
+            "integrity": "sha512-UT0f4t+3sQ/GKW7875NiIIjZJ1Bh4gd7JNfoIkwIQyWqO7wGd0Pqzu0Ho30Ka8MNF5lm++SkVeqAk26vGxoUpg==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
-                "@stylistic/eslint-plugin-js": "2.3.0",
-                "@stylistic/eslint-plugin-jsx": "2.3.0",
-                "@stylistic/eslint-plugin-plus": "2.3.0",
-                "@stylistic/eslint-plugin-ts": "2.3.0",
-                "@types/eslint": "^8.56.10"
+                "@stylistic/eslint-plugin-js": "2.6.1",
+                "@stylistic/eslint-plugin-jsx": "2.6.1",
+                "@stylistic/eslint-plugin-plus": "2.6.1",
+                "@stylistic/eslint-plugin-ts": "2.6.1",
+                "@types/eslint": "^9.6.0"
             },
             "engines": {
                 "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -279,16 +279,16 @@
             }
         },
         "node_modules/@stylistic/eslint-plugin-js": {
-            "version": "2.3.0",
-            "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-2.3.0.tgz",
-            "integrity": "sha512-lQwoiYb0Fs6Yc5QS3uT8+T9CPKK2Eoxc3H8EnYJgM26v/DgtW+1lvy2WNgyBflU+ThShZaHm3a6CdD9QeKx23w==",
+            "version": "2.6.1",
+            "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-2.6.1.tgz",
+            "integrity": "sha512-iLOiVzcvqzDGD9U0EuVOX680v+XOPiPAjkxWj+Q6iV2GLOM5NB27tKVOpJY7AzBhidwpRbaLTgg3T4UzYx09jw==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
-                "@types/eslint": "^8.56.10",
-                "acorn": "^8.11.3",
+                "@types/eslint": "^9.6.0",
+                "acorn": "^8.12.1",
                 "eslint-visitor-keys": "^4.0.0",
-                "espree": "^10.0.1"
+                "espree": "^10.1.0"
             },
             "engines": {
                 "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -298,14 +298,14 @@
             }
         },
         "node_modules/@stylistic/eslint-plugin-jsx": {
-            "version": "2.3.0",
-            "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-jsx/-/eslint-plugin-jsx-2.3.0.tgz",
-            "integrity": "sha512-tsQ0IEKB195H6X9A4iUSgLLLKBc8gUBWkBIU8tp1/3g2l8stu+PtMQVV/VmK1+3bem5FJCyvfcZIQ/WF1fsizA==",
+            "version": "2.6.1",
+            "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-jsx/-/eslint-plugin-jsx-2.6.1.tgz",
+            "integrity": "sha512-5qHLXqxfY6jubAQfDqrifv41fx7gaqA9svDaChxMI6JiHpEBfh+PXxmm3g+B8gJCYVBTC62Rjl0Ny5QabK58bw==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
-                "@stylistic/eslint-plugin-js": "^2.3.0",
-                "@types/eslint": "^8.56.10",
+                "@stylistic/eslint-plugin-js": "^2.6.1",
+                "@types/eslint": "^9.6.0",
                 "estraverse": "^5.3.0",
                 "picomatch": "^4.0.2"
             },
@@ -317,29 +317,29 @@
             }
         },
         "node_modules/@stylistic/eslint-plugin-plus": {
-            "version": "2.3.0",
-            "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-2.3.0.tgz",
-            "integrity": "sha512-xboPWGUU5yaPlR+WR57GwXEuY4PSlPqA0C3IdNA/+1o2MuBi95XgDJcZiJ9N+aXsqBXAPIpFFb+WQ7QEHo4f7g==",
+            "version": "2.6.1",
+            "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-2.6.1.tgz",
+            "integrity": "sha512-z/IYu/q8ipApzNam5utSU+BrXg4pK/Gv9xNbr4eWv/bZppvTWJU62xCO4nw/6r2dHNPnqc7uCHEC7GMlBnPY0A==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
-                "@types/eslint": "^8.56.10",
-                "@typescript-eslint/utils": "^7.12.0"
+                "@types/eslint": "^9.6.0",
+                "@typescript-eslint/utils": "^8.0.0"
             },
             "peerDependencies": {
                 "eslint": "*"
             }
         },
         "node_modules/@stylistic/eslint-plugin-ts": {
-            "version": "2.3.0",
-            "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-2.3.0.tgz",
-            "integrity": "sha512-wqOR38/uz/0XPnHX68ftp8sNMSAqnYGjovOTN7w00xnjS6Lxr3Sk7q6AaxWWqbMvOj7V2fQiMC5HWAbTruJsCg==",
+            "version": "2.6.1",
+            "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-2.6.1.tgz",
+            "integrity": "sha512-Mxl1VMorEG1Hc6oBYPD0+KIJOWkjEF1R0liL7wWgKfwpqOkgmnh5lVdZBrYyfRKOE4RlGcwEFTNai1IW6orgVg==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
-                "@stylistic/eslint-plugin-js": "2.3.0",
-                "@types/eslint": "^8.56.10",
-                "@typescript-eslint/utils": "^7.12.0"
+                "@stylistic/eslint-plugin-js": "2.6.1",
+                "@types/eslint": "^9.6.0",
+                "@typescript-eslint/utils": "^8.0.0"
             },
             "engines": {
                 "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -349,9 +349,9 @@
             }
         },
         "node_modules/@types/eslint": {
-            "version": "8.56.10",
-            "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz",
-            "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==",
+            "version": "9.6.0",
+            "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.0.tgz",
+            "integrity": "sha512-gi6WQJ7cHRgZxtkQEoyHMppPjq9Kxo5Tjn2prSKDSmZrCz8TZ3jSRCeTJm+WoM+oB0WG37bRqLzaaU3q7JypGg==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
@@ -384,42 +384,42 @@
             "license": "MIT"
         },
         "node_modules/@types/node": {
-            "version": "20.14.11",
-            "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz",
-            "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==",
+            "version": "22.0.2",
+            "resolved": "https://registry.npmjs.org/@types/node/-/node-22.0.2.tgz",
+            "integrity": "sha512-yPL6DyFwY5PiMVEwymNeqUTKsDczQBJ/5T7W/46RwLU/VH+AA8aT5TZkvBviLKLbbm0hlfftEkGrNzfRk/fofQ==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
-                "undici-types": "~5.26.4"
+                "undici-types": "~6.11.1"
             }
         },
         "node_modules/@typescript-eslint/eslint-plugin": {
-            "version": "7.16.1",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz",
-            "integrity": "sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==",
+            "version": "8.0.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.0.0.tgz",
+            "integrity": "sha512-STIZdwEQRXAHvNUS6ILDf5z3u95Gc8jzywunxSNqX00OooIemaaNIA0vEgynJlycL5AjabYLLrIyHd4iazyvtg==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
                 "@eslint-community/regexpp": "^4.10.0",
-                "@typescript-eslint/scope-manager": "7.16.1",
-                "@typescript-eslint/type-utils": "7.16.1",
-                "@typescript-eslint/utils": "7.16.1",
-                "@typescript-eslint/visitor-keys": "7.16.1",
+                "@typescript-eslint/scope-manager": "8.0.0",
+                "@typescript-eslint/type-utils": "8.0.0",
+                "@typescript-eslint/utils": "8.0.0",
+                "@typescript-eslint/visitor-keys": "8.0.0",
                 "graphemer": "^1.4.0",
                 "ignore": "^5.3.1",
                 "natural-compare": "^1.4.0",
                 "ts-api-utils": "^1.3.0"
             },
             "engines": {
-                "node": "^18.18.0 || >=20.0.0"
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
             },
             "funding": {
                 "type": "opencollective",
                 "url": "https://opencollective.com/typescript-eslint"
             },
             "peerDependencies": {
-                "@typescript-eslint/parser": "^7.0.0",
-                "eslint": "^8.56.0"
+                "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0",
+                "eslint": "^8.57.0 || ^9.0.0"
             },
             "peerDependenciesMeta": {
                 "typescript": {
@@ -428,27 +428,27 @@
             }
         },
         "node_modules/@typescript-eslint/parser": {
-            "version": "7.16.1",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.1.tgz",
-            "integrity": "sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA==",
+            "version": "8.0.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.0.0.tgz",
+            "integrity": "sha512-pS1hdZ+vnrpDIxuFXYQpLTILglTjSYJ9MbetZctrUawogUsPdz31DIIRZ9+rab0LhYNTsk88w4fIzVheiTbWOQ==",
             "dev": true,
             "license": "BSD-2-Clause",
             "dependencies": {
-                "@typescript-eslint/scope-manager": "7.16.1",
-                "@typescript-eslint/types": "7.16.1",
-                "@typescript-eslint/typescript-estree": "7.16.1",
-                "@typescript-eslint/visitor-keys": "7.16.1",
+                "@typescript-eslint/scope-manager": "8.0.0",
+                "@typescript-eslint/types": "8.0.0",
+                "@typescript-eslint/typescript-estree": "8.0.0",
+                "@typescript-eslint/visitor-keys": "8.0.0",
                 "debug": "^4.3.4"
             },
             "engines": {
-                "node": "^18.18.0 || >=20.0.0"
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
             },
             "funding": {
                 "type": "opencollective",
                 "url": "https://opencollective.com/typescript-eslint"
             },
             "peerDependencies": {
-                "eslint": "^8.56.0"
+                "eslint": "^8.57.0 || ^9.0.0"
             },
             "peerDependenciesMeta": {
                 "typescript": {
@@ -457,17 +457,17 @@
             }
         },
         "node_modules/@typescript-eslint/scope-manager": {
-            "version": "7.16.1",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz",
-            "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==",
+            "version": "8.0.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.0.0.tgz",
+            "integrity": "sha512-V0aa9Csx/ZWWv2IPgTfY7T4agYwJyILESu/PVqFtTFz9RIS823mAze+NbnBI8xiwdX3iqeQbcTYlvB04G9wyQw==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
-                "@typescript-eslint/types": "7.16.1",
-                "@typescript-eslint/visitor-keys": "7.16.1"
+                "@typescript-eslint/types": "8.0.0",
+                "@typescript-eslint/visitor-keys": "8.0.0"
             },
             "engines": {
-                "node": "^18.18.0 || >=20.0.0"
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
             },
             "funding": {
                 "type": "opencollective",
@@ -475,27 +475,24 @@
             }
         },
         "node_modules/@typescript-eslint/type-utils": {
-            "version": "7.16.1",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.1.tgz",
-            "integrity": "sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==",
+            "version": "8.0.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.0.0.tgz",
+            "integrity": "sha512-mJAFP2mZLTBwAn5WI4PMakpywfWFH5nQZezUQdSKV23Pqo6o9iShQg1hP2+0hJJXP2LnZkWPphdIq4juYYwCeg==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
-                "@typescript-eslint/typescript-estree": "7.16.1",
-                "@typescript-eslint/utils": "7.16.1",
+                "@typescript-eslint/typescript-estree": "8.0.0",
+                "@typescript-eslint/utils": "8.0.0",
                 "debug": "^4.3.4",
                 "ts-api-utils": "^1.3.0"
             },
             "engines": {
-                "node": "^18.18.0 || >=20.0.0"
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
             },
             "funding": {
                 "type": "opencollective",
                 "url": "https://opencollective.com/typescript-eslint"
             },
-            "peerDependencies": {
-                "eslint": "^8.56.0"
-            },
             "peerDependenciesMeta": {
                 "typescript": {
                     "optional": true
@@ -503,13 +500,13 @@
             }
         },
         "node_modules/@typescript-eslint/types": {
-            "version": "7.16.1",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz",
-            "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==",
+            "version": "8.0.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.0.0.tgz",
+            "integrity": "sha512-wgdSGs9BTMWQ7ooeHtu5quddKKs5Z5dS+fHLbrQI+ID0XWJLODGMHRfhwImiHoeO2S5Wir2yXuadJN6/l4JRxw==",
             "dev": true,
             "license": "MIT",
             "engines": {
-                "node": "^18.18.0 || >=20.0.0"
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
             },
             "funding": {
                 "type": "opencollective",
@@ -517,14 +514,14 @@
             }
         },
         "node_modules/@typescript-eslint/typescript-estree": {
-            "version": "7.16.1",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz",
-            "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==",
+            "version": "8.0.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.0.0.tgz",
+            "integrity": "sha512-5b97WpKMX+Y43YKi4zVcCVLtK5F98dFls3Oxui8LbnmRsseKenbbDinmvxrWegKDMmlkIq/XHuyy0UGLtpCDKg==",
             "dev": true,
             "license": "BSD-2-Clause",
             "dependencies": {
-                "@typescript-eslint/types": "7.16.1",
-                "@typescript-eslint/visitor-keys": "7.16.1",
+                "@typescript-eslint/types": "8.0.0",
+                "@typescript-eslint/visitor-keys": "8.0.0",
                 "debug": "^4.3.4",
                 "globby": "^11.1.0",
                 "is-glob": "^4.0.3",
@@ -533,7 +530,7 @@
                 "ts-api-utils": "^1.3.0"
             },
             "engines": {
-                "node": "^18.18.0 || >=20.0.0"
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
             },
             "funding": {
                 "type": "opencollective",
@@ -546,40 +543,40 @@
             }
         },
         "node_modules/@typescript-eslint/utils": {
-            "version": "7.16.1",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz",
-            "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==",
+            "version": "8.0.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.0.0.tgz",
+            "integrity": "sha512-k/oS/A/3QeGLRvOWCg6/9rATJL5rec7/5s1YmdS0ZU6LHveJyGFwBvLhSRBv6i9xaj7etmosp+l+ViN1I9Aj/Q==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
                 "@eslint-community/eslint-utils": "^4.4.0",
-                "@typescript-eslint/scope-manager": "7.16.1",
-                "@typescript-eslint/types": "7.16.1",
-                "@typescript-eslint/typescript-estree": "7.16.1"
+                "@typescript-eslint/scope-manager": "8.0.0",
+                "@typescript-eslint/types": "8.0.0",
+                "@typescript-eslint/typescript-estree": "8.0.0"
             },
             "engines": {
-                "node": "^18.18.0 || >=20.0.0"
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
             },
             "funding": {
                 "type": "opencollective",
                 "url": "https://opencollective.com/typescript-eslint"
             },
             "peerDependencies": {
-                "eslint": "^8.56.0"
+                "eslint": "^8.57.0 || ^9.0.0"
             }
         },
         "node_modules/@typescript-eslint/visitor-keys": {
-            "version": "7.16.1",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz",
-            "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==",
+            "version": "8.0.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.0.0.tgz",
+            "integrity": "sha512-oN0K4nkHuOyF3PVMyETbpP5zp6wfyOvm7tWhTMfoqxSSsPmJIh6JNASuZDlODE8eE+0EB9uar+6+vxr9DBTYOA==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
-                "@typescript-eslint/types": "7.16.1",
+                "@typescript-eslint/types": "8.0.0",
                 "eslint-visitor-keys": "^3.4.3"
             },
             "engines": {
-                "node": "^18.18.0 || >=20.0.0"
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
             },
             "funding": {
                 "type": "opencollective",
@@ -802,9 +799,9 @@
             }
         },
         "node_modules/debug": {
-            "version": "4.3.5",
-            "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
-            "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
+            "version": "4.3.6",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
+            "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
@@ -860,17 +857,17 @@
             }
         },
         "node_modules/eslint": {
-            "version": "9.7.0",
-            "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.7.0.tgz",
-            "integrity": "sha512-FzJ9D/0nGiCGBf8UXO/IGLTgLVzIxze1zpfA8Ton2mjLovXdAPlYDv+MQDcqj3TmrhAGYfOpz9RfR+ent0AgAw==",
+            "version": "9.8.0",
+            "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.8.0.tgz",
+            "integrity": "sha512-K8qnZ/QJzT2dLKdZJVX6W4XOwBzutMYmt0lqUS+JdXgd+HTYFlonFgkJ8s44d/zMPPCnOOk0kMWCApCPhiOy9A==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
                 "@eslint-community/eslint-utils": "^4.2.0",
                 "@eslint-community/regexpp": "^4.11.0",
-                "@eslint/config-array": "^0.17.0",
+                "@eslint/config-array": "^0.17.1",
                 "@eslint/eslintrc": "^3.1.0",
-                "@eslint/js": "9.7.0",
+                "@eslint/js": "9.8.0",
                 "@humanwhocodes/module-importer": "^1.0.1",
                 "@humanwhocodes/retry": "^0.3.0",
                 "@nodelib/fs.walk": "^1.2.8",
@@ -912,9 +909,9 @@
             }
         },
         "node_modules/eslint-plugin-jsdoc": {
-            "version": "48.7.0",
-            "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.7.0.tgz",
-            "integrity": "sha512-5oiVf7Y+ZxGYQTlLq81X72n+S+hjvS/u0upAdbpPEeaIZILK3MKN8lm/6QqKioBjm/qZ0B5XpMQUtc2fUkqXAg==",
+            "version": "48.10.2",
+            "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.10.2.tgz",
+            "integrity": "sha512-xTkf/MmEeVrTbezc6kDqCJmK9RcseIKo8X4oyoDCMvV4LY8dqrQi8kmfRrv9n0gNBkCclevaOh2Lkmu6Fs8SLg==",
             "dev": true,
             "license": "BSD-3-Clause",
             "dependencies": {
@@ -923,11 +920,12 @@
                 "comment-parser": "1.4.1",
                 "debug": "^4.3.5",
                 "escape-string-regexp": "^4.0.0",
+                "espree": "^10.1.0",
                 "esquery": "^1.6.0",
                 "parse-imports": "^2.1.1",
-                "semver": "^7.6.2",
+                "semver": "^7.6.3",
                 "spdx-expression-parse": "^4.0.0",
-                "synckit": "^0.9.0"
+                "synckit": "^0.9.1"
             },
             "engines": {
                 "node": ">=18"
@@ -1888,9 +1886,9 @@
             }
         },
         "node_modules/typescript": {
-            "version": "5.5.3",
-            "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz",
-            "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==",
+            "version": "5.5.4",
+            "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
+            "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
             "dev": true,
             "license": "Apache-2.0",
             "bin": {
@@ -1902,26 +1900,23 @@
             }
         },
         "node_modules/typescript-eslint": {
-            "version": "7.16.1",
-            "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.16.1.tgz",
-            "integrity": "sha512-889oE5qELj65q/tGeOSvlreNKhimitFwZqQ0o7PcWC7/lgRkAMknznsCsV8J8mZGTP/Z+cIbX8accf2DE33hrA==",
+            "version": "8.0.0",
+            "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.0.0.tgz",
+            "integrity": "sha512-yQWBJutWL1PmpmDddIOl9/Mi6vZjqNCjqSGBMQ4vsc2Aiodk0SnbQQWPXbSy0HNuKCuGkw1+u4aQ2mO40TdhDQ==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
-                "@typescript-eslint/eslint-plugin": "7.16.1",
-                "@typescript-eslint/parser": "7.16.1",
-                "@typescript-eslint/utils": "7.16.1"
+                "@typescript-eslint/eslint-plugin": "8.0.0",
+                "@typescript-eslint/parser": "8.0.0",
+                "@typescript-eslint/utils": "8.0.0"
             },
             "engines": {
-                "node": "^18.18.0 || >=20.0.0"
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
             },
             "funding": {
                 "type": "opencollective",
                 "url": "https://opencollective.com/typescript-eslint"
             },
-            "peerDependencies": {
-                "eslint": "^8.56.0"
-            },
             "peerDependenciesMeta": {
                 "typescript": {
                     "optional": true
@@ -1929,9 +1924,9 @@
             }
         },
         "node_modules/undici-types": {
-            "version": "5.26.5",
-            "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
-            "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
+            "version": "6.11.1",
+            "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.11.1.tgz",
+            "integrity": "sha512-mIDEX2ek50x0OlRgxryxsenE5XaQD4on5U2inY7RApK3SOJpofyw7uW2AyfMKkhAxXIceo2DeWGVGwyvng1GNQ==",
             "dev": true,
             "license": "MIT"
         },
diff --git a/modules/ags/config/package.json b/modules/ags/config/package.json
index 1ffeb4c3..27b9b510 100644
--- a/modules/ags/config/package.json
+++ b/modules/ags/config/package.json
@@ -5,16 +5,13 @@
         "fzf": "0.5.2"
     },
     "devDependencies": {
-        "@eslint/js": "9.7.0",
-        "@stylistic/eslint-plugin": "2.3.0",
+        "@eslint/js": "9.8.0",
+        "@stylistic/eslint-plugin": "2.6.1",
         "@types/eslint__js": "8.42.3",
-        "@types/node": "20.14.11",
-        "eslint": "9.7.0",
-        "eslint-plugin-jsdoc": "48.7.0",
-        "typescript": "5.5.3",
-        "typescript-eslint": "7.16.1"
-    },
-    "overrides": {
-        "eslint": "$eslint"
+        "@types/node": "22.0.2",
+        "eslint": "9.8.0",
+        "eslint-plugin-jsdoc": "48.10.2",
+        "typescript": "5.5.4",
+        "typescript-eslint": "8.0.0"
     }
 }
diff --git a/modules/ags/config/services/brightness.ts b/modules/ags/config/services/brightness.ts
index 93b26901..48826c68 100644
--- a/modules/ags/config/services/brightness.ts
+++ b/modules/ags/config/services/brightness.ts
@@ -41,22 +41,6 @@ class Brightness extends Service {
         return this.#kbd;
     }
 
-    get screen() {
-        return this.#screen;
-    }
-
-    get screenIcon() {
-        return this.#screenIcon;
-    }
-
-    get caps() {
-        return this.#caps;
-    }
-
-    get capsIcon() {
-        return this.#capsIcon;
-    }
-
     set kbd(value) {
         if (value < 0 || value > this.#kbdMax) {
             return;
@@ -70,6 +54,10 @@ class Brightness extends Service {
             .catch(console.error);
     }
 
+    get screen() {
+        return this.#screen;
+    }
+
     set screen(percent) {
         if (percent < 0) {
             percent = 0;
@@ -88,16 +76,27 @@ class Brightness extends Service {
             .catch(console.error);
     }
 
+    get screenIcon() {
+        return this.#screenIcon;
+    }
+
+    get caps() {
+        return this.#caps;
+    }
+
+    get capsIcon() {
+        return this.#capsIcon;
+    }
+
     constructor() {
         super();
         try {
             this.#monitorKbdState();
             this.#kbdMax = Number(exec(`brightnessctl -d ${KBD} m`));
             this.#caps = Number(exec(`bash -c brightnessctl -d ${this.#capsName} g`));
-            this.#screen = Number(exec('brightnessctl g')) /
-                Number(exec('brightnessctl m'));
+            this.#screen = Number(exec('brightnessctl g')) / Number(exec('brightnessctl m'));
         }
-        catch (error) {
+        catch (_e) {
             console.error('missing dependancy: brightnessctl');
         }
     }
@@ -140,6 +139,7 @@ class Brightness extends Service {
                     }
                 },
             ).catch(() => {
+                // @ts-expect-error this works in ags
                 interval.destroy();
             });
         }, INTERVAL);
diff --git a/modules/ags/config/services/clipboard.ts b/modules/ags/config/services/clipboard.ts
index b884510a..9c5bbcc6 100644
--- a/modules/ags/config/services/clipboard.ts
+++ b/modules/ags/config/services/clipboard.ts
@@ -16,7 +16,7 @@ class Clipboard extends Service {
     // Class Attributes
     private _clips_left = 0;
 
-    private _clips: Map<number, { clip: string; isImage: boolean }> = new Map();
+    private _clips = new Map<number, { clip: string, isImage: boolean }>();
 
     get clips() {
         return this._clips;
@@ -75,7 +75,7 @@ class Clipboard extends Service {
 
             this._clips_left = Math.min(rawClips.length - 1, n);
 
-            rawClips.forEach(async (clip, i) => {
+            rawClips.forEach(async(clip, i) => {
                 if (i > n) {
                     return;
                 }
@@ -83,7 +83,7 @@ class Clipboard extends Service {
                 if (clip.includes('img')) {
                     this._decrementClipsLeft();
 
-                    const newClip: [number, {clip: string; isImage: boolean;}] = [
+                    const newClip: [number, { clip: string, isImage: boolean }] = [
                         parseInt((clip.match('[0-9]+') ?? [''])[0]),
                         {
                             clip,
@@ -98,7 +98,7 @@ class Clipboard extends Service {
                     const decodedClip = await this._decodeItem(clip);
 
                     if (decodedClip) {
-                        const newClip: [number, {clip: string; isImage: boolean;}] = [
+                        const newClip: [number, { clip: string, isImage: boolean }] = [
                             parseInt(clip),
                             {
                                 clip: decodedClip,
@@ -120,7 +120,7 @@ class Clipboard extends Service {
             () => {
                 this._getHistory(1);
             },
-            () => {/**/},
+            () => { /**/ },
         );
     }
 }
diff --git a/modules/ags/config/services/gpu-screen-recorder.ts b/modules/ags/config/services/gpu-screen-recorder.ts
index 5fcf911e..4e62305d 100644
--- a/modules/ags/config/services/gpu-screen-recorder.ts
+++ b/modules/ags/config/services/gpu-screen-recorder.ts
@@ -57,7 +57,7 @@ class GSR extends Service {
                     },
                 );
             },
-            () => {/**/},
+            () => { /**/ },
         );
     }
 
diff --git a/modules/ags/config/services/pointers.ts b/modules/ags/config/services/pointers.ts
index 28986360..ee073ef3 100644
--- a/modules/ags/config/services/pointers.ts
+++ b/modules/ags/config/services/pointers.ts
@@ -14,27 +14,27 @@ const ON_CLICK_TRIGGERS = [
 // Types
 import { PopupWindow } from 'global-types';
 import { Subprocess } from 'types/@girs/gio-2.0/gio-2.0.cjs';
-type Layer = {
-    address: string;
-    x: number;
-    y: number;
-    w: number;
-    h: number;
-    namespace: string;
-};
-type Levels = {
-    0?: Array<Layer> | null;
-    1?: Array<Layer> | null;
-    2?: Array<Layer> | null;
-    3?: Array<Layer> | null;
-};
-type Layers = {
-    levels: Levels;
-};
-type CursorPos = {
-    x: number;
-    y: number;
-};
+interface Layer {
+    address: string
+    x: number
+    y: number
+    w: number
+    h: number
+    namespace: string
+}
+interface Levels {
+    0?: Layer[] | null
+    1?: Layer[] | null
+    2?: Layer[] | null
+    3?: Layer[] | null
+}
+interface Layers {
+    levels: Levels
+}
+interface CursorPos {
+    x: number
+    y: number
+}
 
 
 class Pointers extends Service {
@@ -51,7 +51,7 @@ class Pointers extends Service {
 
     #process = null as Subprocess | null;
     #lastLine = '';
-    #pointers = [] as Array<string>;
+    #pointers = [] as string[];
 
     get process() {
         return this.#process;
@@ -111,12 +111,12 @@ class Pointers extends Service {
     #initAppConnection() {
         App.connect('window-toggled', () => {
             const anyVisibleAndClosable =
-                (App.windows as Array<PopupWindow>).some((w) => {
+                (App.windows as PopupWindow[]).some((w) => {
                     const closable = w.close_on_unfocus &&
-                        !(
-                            w.close_on_unfocus === 'none' ||
-                            w.close_on_unfocus === 'stay'
-                        );
+                      !(
+                          w.close_on_unfocus === 'none' ||
+                          w.close_on_unfocus === 'stay'
+                      );
 
                     return w.visible && closable;
                 });
@@ -132,7 +132,7 @@ class Pointers extends Service {
     }
 
     static detectClickedOutside(clickStage: string) {
-        const toClose = ((App.windows as Array<PopupWindow>)).some((w) => {
+        const toClose = ((App.windows as PopupWindow[])).some((w) => {
             const closable = (
                 w.close_on_unfocus &&
                 w.close_on_unfocus === clickStage
@@ -160,8 +160,8 @@ class Pointers extends Service {
                             'osk',
                         ];
 
-                        const getNoCloseWidgets = (names: Array<string>) => {
-                            const arr = [] as Array<Layer>;
+                        const getNoCloseWidgets = (names: string[]) => {
+                            const arr = [] as Layer[];
 
                             names.forEach((name) => {
                                 arr.push(
@@ -184,7 +184,7 @@ class Pointers extends Service {
                         };
                         const clickIsOnWidget = (w: Layer) => {
                             return pos.x > w.x && pos.x < w.x + w.w &&
-                                   pos.y > w.y && pos.y < w.y + w.h;
+                              pos.y > w.y && pos.y < w.y + w.h;
                         };
 
                         const noCloseWidgets =
@@ -200,9 +200,9 @@ class Pointers extends Service {
                             }
 
                             return window &&
-                                window.close_on_unfocus &&
-                                window.close_on_unfocus ===
-                                    clickStage;
+                              window.close_on_unfocus &&
+                              window.close_on_unfocus ===
+                              clickStage;
                         });
 
                         if (noCloseWidgets.some(clickIsOnWidget)) {
@@ -212,7 +212,7 @@ class Pointers extends Service {
                             widgets.forEach(
                                 (w) => {
                                     if (!(pos.x > w.x && pos.x < w.x + w.w &&
-                                          pos.y > w.y && pos.y < w.y + w.h)) {
+                                      pos.y > w.y && pos.y < w.y + w.h)) {
                                         App.closeWindow(w.namespace);
                                     }
                                 },
diff --git a/modules/ags/config/ts/applauncher/launch.ts b/modules/ags/config/ts/applauncher/launch.ts
index f6bce099..26323887 100644
--- a/modules/ags/config/ts/applauncher/launch.ts
+++ b/modules/ags/config/ts/applauncher/launch.ts
@@ -5,7 +5,7 @@ import { Application } from 'types/service/applications.ts';
 const bash = async(strings: TemplateStringsArray | string, ...values: unknown[]) => {
     const cmd = typeof strings === 'string' ?
         strings :
-        strings.flatMap((str, i) => `${str }${values[i] ?? ''}`)
+        strings.flatMap((str, i) => `${str}${values[i] ?? ''}`)
             .join('');
 
     return Utils.execAsync(['bash', '-c', cmd]).catch((err) => {
diff --git a/modules/ags/config/ts/applauncher/main.ts b/modules/ags/config/ts/applauncher/main.ts
index 59173f70..8b331788 100644
--- a/modules/ags/config/ts/applauncher/main.ts
+++ b/modules/ags/config/ts/applauncher/main.ts
@@ -69,7 +69,7 @@ export default () => {
             rows.forEach((row) => {
                 row.changed();
 
-                const item = (row.get_children()[0] as AgsAppItem);
+                const item = row.get_children()[0] as AgsAppItem;
 
                 if (item.attribute.app) {
                     const isMatching = fzfResults.some((r) => {
diff --git a/modules/ags/config/ts/bar/fullscreen.ts b/modules/ags/config/ts/bar/fullscreen.ts
index 7090bf43..f628b310 100644
--- a/modules/ags/config/ts/bar/fullscreen.ts
+++ b/modules/ags/config/ts/bar/fullscreen.ts
@@ -27,7 +27,7 @@ Hyprland.connect('event', (hyprObj) => {
         const mon = Hyprland.getMonitor(c.monitor);
 
         return c.fullscreen &&
-            c.workspace.id === mon?.activeWorkspace.id;
+          c.workspace.id === mon?.activeWorkspace.id;
     });
 
     const monitors = fsClients.map((c) =>
diff --git a/modules/ags/config/ts/bar/hovers/network.ts b/modules/ags/config/ts/bar/hovers/network.ts
index 0280a8ff..5ced3d93 100644
--- a/modules/ags/config/ts/bar/hovers/network.ts
+++ b/modules/ags/config/ts/bar/hovers/network.ts
@@ -9,11 +9,11 @@ export default () => HoverRevealer({
 
     icon: Icon().hook(Network, (self) => {
         if (Network.wifi.internet === 'connected' ||
-            Network.wifi.internet === 'connecting') {
+          Network.wifi.internet === 'connecting') {
             self.icon = Network.wifi.icon_name;
         }
         else if (Network.wired.internet === 'connected' ||
-                 Network.wired.internet === 'connecting') {
+          Network.wired.internet === 'connecting') {
             self.icon = Network.wired.icon_name;
         }
         else {
@@ -23,11 +23,11 @@ export default () => HoverRevealer({
 
     label: Label().hook(Network, (self) => {
         if (Network.wifi.internet === 'connected' ||
-            Network.wifi.internet === 'connecting') {
+          Network.wifi.internet === 'connecting') {
             self.label = Network.wifi.ssid || 'Unknown';
         }
         else if (Network.wired.internet === 'connected' ||
-                 Network.wired.internet === 'connecting') {
+          Network.wired.internet === 'connecting') {
             self.label = 'Connected';
         }
         else {
diff --git a/modules/ags/config/ts/bar/items/workspaces.ts b/modules/ags/config/ts/bar/items/workspaces.ts
index b7ca7c23..f46c6d6e 100644
--- a/modules/ags/config/ts/bar/items/workspaces.ts
+++ b/modules/ags/config/ts/bar/items/workspaces.ts
@@ -50,7 +50,7 @@ const Workspace = ({ id }: { id: number }) => {
                         // Deal with urgent windows
                         const client = Hyprland.getClient(addr);
                         const isThisUrgent = client &&
-                            client.workspace.id === id;
+                          client.workspace.id === id;
 
                         if (isThisUrgent) {
                             self.toggleClassName('urgent', true);
diff --git a/modules/ags/config/ts/date/binto.ts b/modules/ags/config/ts/date/binto.ts
index 484bf8c8..d3f34ec8 100644
--- a/modules/ags/config/ts/date/binto.ts
+++ b/modules/ags/config/ts/date/binto.ts
@@ -3,10 +3,12 @@ import CalendarWidget from './main.ts';
 import { get_gdkmonitor_from_desc } from '../lib.ts';
 
 
+const RIGHT_MARGIN = 20;
+
 export default () => PopupWindow({
     name: 'calendar',
     anchor: ['bottom', 'right'],
-    margins: [0, 20, 0, 0],
+    margins: [0, RIGHT_MARGIN, 0, 0],
     transition: 'slide bottom',
     gdkmonitor: get_gdkmonitor_from_desc('desc:Acer Technologies Acer K212HQL T3EAA0014201'),
 
diff --git a/modules/ags/config/ts/lockscreen/lock.ts b/modules/ags/config/ts/lockscreen/lock.ts
index 5c57b50e..859b0898 100644
--- a/modules/ags/config/ts/lockscreen/lock.ts
+++ b/modules/ags/config/ts/lockscreen/lock.ts
@@ -15,8 +15,8 @@ import { Box as AgsBox } from 'types/widgets/box';
 
 
 const lock = Lock.prepare_lock();
-const windows: Map<Gdk.Monitor, Gtk.Window> = new Map();
-const blurBGs: AgsBox<Gtk.Widget, { geometry: { w: number, h: number }; }>[] = [];
+const windows = new Map<Gdk.Monitor, Gtk.Window>();
+const blurBGs: AgsBox<Gtk.Widget, { geometry: { w: number, h: number } }>[] = [];
 
 const transition_duration = 1000;
 const WINDOW_MARGINS = -2;
diff --git a/modules/ags/config/ts/media-player/gesture.ts b/modules/ags/config/ts/media-player/gesture.ts
index b4ad7271..926c1c7e 100644
--- a/modules/ags/config/ts/media-player/gesture.ts
+++ b/modules/ags/config/ts/media-player/gesture.ts
@@ -19,7 +19,7 @@ import {
 
 
 export default ({
-    setup = () => {/**/},
+    setup = () => { /**/ },
     ...props
 }: Gesture) => {
     const widget = EventBox();
diff --git a/modules/ags/config/ts/misc/closer.ts b/modules/ags/config/ts/misc/closer.ts
index a3d7e0ae..60a7c300 100644
--- a/modules/ags/config/ts/misc/closer.ts
+++ b/modules/ags/config/ts/misc/closer.ts
@@ -3,10 +3,10 @@ import { PopupWindow } from 'global-types';
 
 
 export default () => {
-    (App.windows as Array<PopupWindow>)
+    (App.windows as PopupWindow[])
         .filter((w) => w &&
-            w.close_on_unfocus &&
-            w.close_on_unfocus !== 'stay')
+          w.close_on_unfocus &&
+          w.close_on_unfocus !== 'stay')
         .forEach((w) => {
             App.closeWindow(w.name);
         });
diff --git a/modules/ags/config/ts/misc/cursorbox.ts b/modules/ags/config/ts/misc/cursorbox.ts
index 67652f23..39bfad58 100644
--- a/modules/ags/config/ts/misc/cursorbox.ts
+++ b/modules/ags/config/ts/misc/cursorbox.ts
@@ -5,6 +5,9 @@ import Gdk from 'gi://Gdk?version=3.0';
 import { BaseProps, Widget as AgsWidget } from 'types/widgets/widget';
 type EventHandler<Self> = (self: Self, event: Gdk.Event) => boolean | unknown;
 
+// eslint-disable-next-line
+export interface CursorBox<Child, Attr> extends AgsWidget<Attr> { }
+
 export type CursorBoxProps<
     Child extends Gtk.Widget,
     Attr = unknown,
@@ -26,10 +29,8 @@ export type CursorBoxProps<
     on_secondary_click_release?: EventHandler<Self>
 }, Attr>;
 
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-export interface CursorBox<Child, Attr> extends AgsWidget<Attr> { }
-
 
+// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
 export class CursorBox<Child extends Gtk.Widget, Attr> extends Gtk.EventBox {
     static {
         Widget.register(this, {
diff --git a/modules/ags/config/ts/misc/persist.ts b/modules/ags/config/ts/misc/persist.ts
index b6d7267a..9ad566a4 100644
--- a/modules/ags/config/ts/misc/persist.ts
+++ b/modules/ags/config/ts/misc/persist.ts
@@ -3,7 +3,7 @@ const { get_home_dir } = imports.gi.GLib;
 
 import GObject from 'types/@girs/gobject-2.0/gobject-2.0';
 
-type Persist = {
+interface Persist {
     name: string
     gobject: GObject.Object
     prop: string
@@ -11,7 +11,7 @@ type Persist = {
     whenTrue?: boolean | string
     whenFalse?: boolean | string
     signal?: string
-};
+}
 
 
 export default ({
diff --git a/modules/ags/config/ts/misc/popup.ts b/modules/ags/config/ts/misc/popup.ts
index 32358916..c7403338 100644
--- a/modules/ags/config/ts/misc/popup.ts
+++ b/modules/ags/config/ts/misc/popup.ts
@@ -8,6 +8,9 @@ import { Window } from 'resource:///com/github/Aylur/ags/widgets/window.js';
 import type { WindowProps } from 'types/widgets/window';
 import type { Widget as AgsWidget } from 'types/widgets/widget';
 
+// eslint-disable-next-line
+export interface PopupWindow<Child, Attr> extends AgsWidget<Attr> { }
+
 import {
     CloseType,
     HyprTransition,
@@ -18,17 +21,15 @@ export type PopupWindowProps<
     Attr = unknown,
     Self = PopupWindow<Child, Attr>,
 > = WindowProps<Child, Attr, Self> & {
-    transition?: HyprTransition;
-    on_open?(self: PopupWindow<Child, Attr>): void;
-    on_close?(self: PopupWindow<Child, Attr>): void;
-    close_on_unfocus?: CloseType;
-    anchor?: Array<'top' | 'bottom' | 'right' | 'left'>;
+    transition?: HyprTransition
+    on_open?(self: PopupWindow<Child, Attr>): void
+    on_close?(self: PopupWindow<Child, Attr>): void
+    close_on_unfocus?: CloseType
+    anchor?: ('top' | 'bottom' | 'right' | 'left')[]
 };
 
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-export interface PopupWindow<Child, Attr> extends AgsWidget<Attr> { }
-
 
+// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
 export class PopupWindow<
     Child extends Gtk.Widget,
     Attr,
@@ -68,6 +69,7 @@ export class PopupWindow<
     }
 
 
+    // eslint-disable-next-line no-use-before-define
     protected _on_open: (self: PopupWindow<Child, Attr>) => void;
 
     get on_open() {
@@ -79,6 +81,7 @@ export class PopupWindow<
     }
 
 
+    // eslint-disable-next-line no-use-before-define
     private _on_close: (self: PopupWindow<Child, Attr>) => void;
 
     get on_close() {
@@ -92,8 +95,8 @@ export class PopupWindow<
 
     constructor({
         transition = 'slide top',
-        on_open = () => {/**/ },
-        on_close = () => {/**/ },
+        on_open = () => { /**/ },
+        on_close = () => { /**/ },
 
         // Window props
         name,
diff --git a/modules/ags/config/ts/misc/sorted-list.ts b/modules/ags/config/ts/misc/sorted-list.ts
index 759b473a..f58dc4bc 100644
--- a/modules/ags/config/ts/misc/sorted-list.ts
+++ b/modules/ags/config/ts/misc/sorted-list.ts
@@ -9,22 +9,24 @@ import { ListBoxRow } from 'types/@girs/gtk-3.0/gtk-3.0.cjs';
 import { Monitor } from 'types/service/hyprland';
 import { Binding } from 'types/service';
 
+// eslint-disable-next-line @typescript-eslint/no-empty-object-type
+export interface SortedList<Attr> extends AgsWidget<Attr> { }
+
+// eslint-disable-next-line no-use-before-define
 type MakeChild = ReturnType<typeof makeChild>;
 
 type SortedListProps<Attr = unknown, Self = SortedList<Attr>> =
-    PopupWindowProps<MakeChild['child'], Attr, Self> & {
-        on_select: (row: ListBoxRow) => void;
-        init_rows?: (list: MakeChild['list']) => void;
-        set_sort: (
-            text: string,
-            list: MakeChild['list'],
-            placeholder: MakeChild['placeholder'],
-        ) => void;
-        setup_list?: (list: MakeChild['list']) => void;
-    };
+  PopupWindowProps<MakeChild['child'], Attr, Self> & {
+      on_select: (row: ListBoxRow) => void
+      init_rows?: (list: MakeChild['list']) => void
+      set_sort: (
+          text: string,
+          list: MakeChild['list'],
+          placeholder: MakeChild['placeholder'],
+      ) => void
+      setup_list?: (list: MakeChild['list']) => void
+  };
 
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-export interface SortedList<Attr> extends AgsWidget<Attr> { }
 
 
 const centerCursor = async(): Promise<void> => {
@@ -108,6 +110,7 @@ const makeChild = (class_name: string | Binding<any, any, string>) => {
     };
 };
 
+// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
 export class SortedList<
     Attr,
 > extends PopupWindow<MakeChild['child'], Attr> {
diff --git a/modules/ags/config/ts/notifications/base.ts b/modules/ags/config/ts/notifications/base.ts
index c7fd424a..b6db822e 100644
--- a/modules/ags/config/ts/notifications/base.ts
+++ b/modules/ags/config/ts/notifications/base.ts
@@ -14,11 +14,11 @@ import { launchApp } from '../applauncher/launch.ts';
 // Types
 import { Notification as NotifObj } from 'types/service/notifications.ts';
 import { Client } from 'types/service/hyprland.ts';
-type NotificationWidget = {
+interface NotificationWidget {
     notif: NotifObj
     slideIn?: 'Left' | 'Right'
     command?(): void
-};
+}
 import {
     CursorBox as CBox,
     EventBoxGeneric,
@@ -46,7 +46,7 @@ const getDragState = (box: EventBoxGeneric) => (box
 
 
 const NotificationIcon = (notif: NotifObj) => {
-    let iconCmd = (box: CBox):void => {
+    let iconCmd = (box: CBox): void => {
         if (!box) {
             console.log();
         }
@@ -66,16 +66,16 @@ const NotificationIcon = (notif: NotifObj) => {
                 if (!getDragState(box)) {
                     if (wmClass === 'Proton Mail') {
                         Hyprland.messageAsync('dispatch ' +
-                            'togglespecialworkspace thunder');
+                        'togglespecialworkspace thunder');
                     }
                     else if (wmClass === 'Spotify') {
                         Hyprland.messageAsync('dispatch ' +
-                            'togglespecialworkspace spot');
+                        'togglespecialworkspace spot');
                     }
                     else {
                         Hyprland.messageAsync('j/clients').then((msg) => {
-                            const clients = JSON.parse(msg) as Array<Client>;
-                            const classes = [] as Array<string>;
+                            const clients = JSON.parse(msg) as Client[];
+                            const classes = [] as string[];
 
                             for (const key of clients) {
                                 if (key.class) {
@@ -85,7 +85,7 @@ const NotificationIcon = (notif: NotifObj) => {
 
                             if (wmClass && classes.includes(wmClass)) {
                                 Hyprland.messageAsync('dispatch ' +
-                                    `focuswindow ^(${wmClass})`);
+                                `focuswindow ^(${wmClass})`);
                             }
                             else {
                                 Hyprland.messageAsync('dispatch workspace empty')
@@ -168,7 +168,7 @@ export const HasNotifs = Variable(false);
 export const Notification = ({
     notif,
     slideIn = 'Left',
-    command = () => {/**/},
+    command = () => { /**/ },
 }: NotificationWidget) => {
     if (!notif) {
         return;
@@ -248,7 +248,7 @@ export const Notification = ({
                                                     notif.close(),
 
                                                 child: Icon('window-close' +
-                                                    '-symbolic'),
+                                                '-symbolic'),
                                             }),
                                         }),
                                     ],
diff --git a/modules/ags/config/ts/notifications/gesture.ts b/modules/ags/config/ts/notifications/gesture.ts
index f655ab20..237fbc81 100644
--- a/modules/ags/config/ts/notifications/gesture.ts
+++ b/modules/ags/config/ts/notifications/gesture.ts
@@ -44,7 +44,7 @@ const defaultStyle = `${TRANSITION} margin: unset; opacity: 1;`;
 export default ({
     id,
     slideIn = 'Left',
-    command = () => {/**/},
+    command = () => { /**/ },
     ...props
 }) => {
     const widget = EventBox({
diff --git a/modules/ags/config/ts/on-screen-keyboard/gesture.ts b/modules/ags/config/ts/on-screen-keyboard/gesture.ts
index e47e8db2..65c16ac4 100644
--- a/modules/ags/config/ts/on-screen-keyboard/gesture.ts
+++ b/modules/ags/config/ts/on-screen-keyboard/gesture.ts
@@ -28,7 +28,7 @@ export default (window: OskWindow) => {
 
     window.child.setCss(`margin-bottom: -${HIDDEN_MARGIN}px;`);
 
-    let signals = [] as Array<number>;
+    let signals = [] as number[];
 
     window.attribute = {
         startY: null,
diff --git a/modules/ags/config/ts/on-screen-keyboard/keys.ts b/modules/ags/config/ts/on-screen-keyboard/keys.ts
index 13cc8ef2..9c44c929 100644
--- a/modules/ags/config/ts/on-screen-keyboard/keys.ts
+++ b/modules/ags/config/ts/on-screen-keyboard/keys.ts
@@ -45,14 +45,14 @@ const LCTRL_CODE = 29;
 
 // Types
 import { Variable as Var } from 'types/variable.ts';
-type Key = {
-    keytype: string,
-    label: string,
-    labelShift?: string,
-    labelAltGr?: string,
-    shape: string,
+interface Key {
+    keytype: string
+    label: string
+    labelShift?: string
+    labelAltGr?: string
+    shape: string
     keycode: number
-};
+}
 
 
 const ModKey = (key: Key) => {
diff --git a/modules/ags/config/ts/osd/main.ts b/modules/ags/config/ts/osd/main.ts
index e4b3e83b..f1d0195f 100644
--- a/modules/ags/config/ts/osd/main.ts
+++ b/modules/ags/config/ts/osd/main.ts
@@ -7,7 +7,7 @@ import PopupWindow from '../misc/popup.ts';
 import { BoxGeneric } from 'global-types';
 
 // Import all the OSDs as an array
-const OSDList = [] as Array<() => BoxGeneric>;
+const OSDList = [] as (() => BoxGeneric)[];
 
 import * as Modules from './osds.ts';
 for (const osd in Modules) {
diff --git a/modules/ags/config/ts/quick-settings/bluetooth.ts b/modules/ags/config/ts/quick-settings/bluetooth.ts
index acedfd8a..824beb63 100644
--- a/modules/ags/config/ts/quick-settings/bluetooth.ts
+++ b/modules/ags/config/ts/quick-settings/bluetooth.ts
@@ -187,7 +187,7 @@ export const BluetoothMenu = () => {
                                     // Make bottom scroll indicator appear only
                                     // when first getting overflowing children
                                     if (!(bottomArrow.reveal_child === true ||
-                                        topArrow.reveal_child === true)) {
+                                      topArrow.reveal_child === true)) {
                                         bottomArrow.reveal_child = true;
                                     }
                                 }
@@ -200,7 +200,7 @@ export const BluetoothMenu = () => {
                             }
 
                             // Trigger sort_func
-                            (self.get_children() as Array<ListBoxRow>)
+                            (self.get_children() as ListBoxRow[])
                                 .forEach((ch) => {
                                     ch.changed();
                                 });
diff --git a/modules/ags/config/ts/quick-settings/button-grid.ts b/modules/ags/config/ts/quick-settings/button-grid.ts
index 536864d9..cc6ae4a7 100644
--- a/modules/ags/config/ts/quick-settings/button-grid.ts
+++ b/modules/ags/config/ts/quick-settings/button-grid.ts
@@ -36,7 +36,7 @@ type IndicatorTuple = [
     signal?: string,
 ];
 
-type GridButtonType = {
+interface GridButtonType {
     command?(): void
     secondary_command?(): void
     on_open?(menu: RevealerGeneric): void
@@ -44,17 +44,17 @@ type GridButtonType = {
     indicator?: IndicatorTuple
     // @ts-expect-error me is lazy
     menu?: Widget
-};
+}
 
 
 // TODO: do vpn button
 const SPACING = 28;
-const ButtonStates = [] as Array<Var<boolean>>;
+const ButtonStates = [] as Var<boolean>[];
 
 const GridButton = ({
-    command = () => {/**/},
-    secondary_command = () => {/**/},
-    on_open = () => {/**/},
+    command = () => { /**/ },
+    secondary_command = () => { /**/ },
+    on_open = () => { /**/ },
     icon,
     indicator,
     menu,
@@ -158,7 +158,7 @@ const GridButton = ({
                                         ?.children[1] as BoxGeneric;
 
                                 const isSetup = (rowMenu
-                                    .get_children() as Array<BoxGeneric>)
+                                    .get_children() as BoxGeneric[])
                                     .find((ch) => ch === menu);
 
                                 if (!isSetup) {
diff --git a/modules/ags/config/ts/quick-settings/network.ts b/modules/ags/config/ts/quick-settings/network.ts
index 3b8cc83e..482fd123 100644
--- a/modules/ags/config/ts/quick-settings/network.ts
+++ b/modules/ags/config/ts/quick-settings/network.ts
@@ -43,7 +43,7 @@ const AccessPoint = (ap: APType) => {
                         self.setCss(
                             `opacity: ${
                                 widget.attribute.ap.value.ssid ===
-                                    Network.wifi.ssid ?
+                                Network.wifi.ssid ?
                                     '1' :
                                     '0'
                             };
@@ -150,7 +150,7 @@ export const NetworkMenu = () => {
                         self.hook(Network, () => {
                             // Add missing APs
                             const currentAPs = Network.wifi
-                                ?.access_points as Array<APType>;
+                                ?.access_points as APType[];
 
                             currentAPs.forEach((ap) => {
                                 if (ap.ssid !== 'Unknown') {
@@ -214,7 +214,7 @@ export const NetworkMenu = () => {
                                     // Make bottom scroll indicator appear only
                                     // when first getting overflowing children
                                     if (!(bottomArrow.reveal_child === true ||
-                                        topArrow.reveal_child === true)) {
+                                      topArrow.reveal_child === true)) {
                                         bottomArrow.reveal_child = true;
                                     }
                                 }
@@ -227,7 +227,7 @@ export const NetworkMenu = () => {
                             }
 
                             // Trigger sort_func
-                            (self.get_children() as Array<ListBoxRow>)
+                            (self.get_children() as ListBoxRow[])
                                 .forEach((ch) => {
                                     ch.changed();
                                 });