62 Commits

Author SHA1 Message Date
dependabot[bot]
2a90e86f4a Bump the minor-and-patch group in /app with 7 updates
Bumps the minor-and-patch group in /app with 7 updates:

| Package | From | To |
| --- | --- | --- |
| [@codemirror/commands](https://github.com/codemirror/commands) | `6.10.0` | `6.10.1` |
| [@codemirror/state](https://github.com/codemirror/state) | `6.5.2` | `6.5.3` |
| [@codemirror/view](https://github.com/codemirror/view) | `6.39.4` | `6.39.5` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `25.0.2` | `25.0.3` |
| [@vitest/coverage-v8](https://github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8) | `4.0.15` | `4.0.16` |
| [sass](https://github.com/sass/dart-sass) | `1.96.0` | `1.97.1` |
| [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) | `4.0.15` | `4.0.16` |


Updates `@codemirror/commands` from 6.10.0 to 6.10.1
- [Changelog](https://github.com/codemirror/commands/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/commands/compare/6.10.0...6.10.1)

Updates `@codemirror/state` from 6.5.2 to 6.5.3
- [Changelog](https://github.com/codemirror/state/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/state/compare/6.5.2...6.5.3)

Updates `@codemirror/view` from 6.39.4 to 6.39.5
- [Changelog](https://github.com/codemirror/view/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/view/compare/6.39.4...6.39.5)

Updates `@types/node` from 25.0.2 to 25.0.3
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `@vitest/coverage-v8` from 4.0.15 to 4.0.16
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.16/packages/coverage-v8)

Updates `sass` from 1.96.0 to 1.97.1
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.96.0...1.97.1)

Updates `vitest` from 4.0.15 to 4.0.16
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.16/packages/vitest)

---
updated-dependencies:
- dependency-name: "@codemirror/commands"
  dependency-version: 6.10.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: "@codemirror/state"
  dependency-version: 6.5.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: "@codemirror/view"
  dependency-version: 6.39.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: "@types/node"
  dependency-version: 25.0.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: "@vitest/coverage-v8"
  dependency-version: 4.0.16
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: sass
  dependency-version: 1.97.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: vitest
  dependency-version: 4.0.16
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-22 16:27:30 +00:00
35331eded2 Merge pull request #107 from lordmathis/dependabot/go_modules/server/minor-and-patch-5a6b86e10b
Bump the minor-and-patch group in /server with 2 updates
2025-12-15 21:36:41 +01:00
dependabot[bot]
1d2bd0d54c Bump the minor-and-patch group in /server with 2 updates
Bumps the minor-and-patch group in /server with 2 updates: [github.com/go-playground/validator/v10](https://github.com/go-playground/validator) and [golang.org/x/crypto](https://github.com/golang/crypto).


Updates `github.com/go-playground/validator/v10` from 10.28.0 to 10.29.0
- [Release notes](https://github.com/go-playground/validator/releases)
- [Commits](https://github.com/go-playground/validator/compare/v10.28.0...v10.29.0)

Updates `golang.org/x/crypto` from 0.45.0 to 0.46.0
- [Commits](https://github.com/golang/crypto/compare/v0.45.0...v0.46.0)

---
updated-dependencies:
- dependency-name: github.com/go-playground/validator/v10
  dependency-version: 10.29.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: golang.org/x/crypto
  dependency-version: 0.46.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 20:31:48 +00:00
1701463204 Merge pull request #108 from lordmathis/dependabot/npm_and_yarn/app/minor-and-patch-79ef3fc08c
Bump the minor-and-patch group in /app with 14 updates
2025-12-15 21:29:31 +01:00
dependabot[bot]
053c642456 Bump the minor-and-patch group in /app with 14 updates
Bumps the minor-and-patch group in /app with 14 updates:

| Package | From | To |
| --- | --- | --- |
| [@codemirror/view](https://github.com/codemirror/view) | `6.38.8` | `6.39.4` |
| [@mantine/core](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/core) | `8.3.9` | `8.3.10` |
| [@mantine/hooks](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/hooks) | `8.3.9` | `8.3.10` |
| [@mantine/modals](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/modals) | `8.3.9` | `8.3.10` |
| [@mantine/notifications](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/notifications) | `8.3.9` | `8.3.10` |
| [@tabler/icons-react](https://github.com/tabler/tabler-icons/tree/HEAD/packages/icons-react) | `3.35.0` | `3.36.0` |
| [react](https://github.com/facebook/react/tree/HEAD/packages/react) | `19.2.1` | `19.2.3` |
| [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) | `19.2.1` | `19.2.3` |
| [@testing-library/react](https://github.com/testing-library/react-testing-library) | `16.3.0` | `16.3.1` |
| [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) | `8.48.1` | `8.49.0` |
| [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) | `8.48.1` | `8.49.0` |
| [eslint](https://github.com/eslint/eslint) | `9.39.1` | `9.39.2` |
| [sass](https://github.com/sass/dart-sass) | `1.94.2` | `1.96.0` |
| [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) | `7.2.7` | `7.3.0` |


Updates `@codemirror/view` from 6.38.8 to 6.39.4
- [Changelog](https://github.com/codemirror/view/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/view/compare/6.38.8...6.39.4)

Updates `@mantine/core` from 8.3.9 to 8.3.10
- [Release notes](https://github.com/mantinedev/mantine/releases)
- [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mantinedev/mantine/commits/8.3.10/packages/@mantine/core)

Updates `@mantine/hooks` from 8.3.9 to 8.3.10
- [Release notes](https://github.com/mantinedev/mantine/releases)
- [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mantinedev/mantine/commits/8.3.10/packages/@mantine/hooks)

Updates `@mantine/modals` from 8.3.9 to 8.3.10
- [Release notes](https://github.com/mantinedev/mantine/releases)
- [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mantinedev/mantine/commits/8.3.10/packages/@mantine/modals)

Updates `@mantine/notifications` from 8.3.9 to 8.3.10
- [Release notes](https://github.com/mantinedev/mantine/releases)
- [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mantinedev/mantine/commits/8.3.10/packages/@mantine/notifications)

Updates `@tabler/icons-react` from 3.35.0 to 3.36.0
- [Release notes](https://github.com/tabler/tabler-icons/releases)
- [Commits](https://github.com/tabler/tabler-icons/commits/v3.36.0/packages/icons-react)

Updates `react` from 19.2.1 to 19.2.3
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.3/packages/react)

Updates `react-dom` from 19.2.1 to 19.2.3
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.3/packages/react-dom)

Updates `@testing-library/react` from 16.3.0 to 16.3.1
- [Release notes](https://github.com/testing-library/react-testing-library/releases)
- [Changelog](https://github.com/testing-library/react-testing-library/blob/main/CHANGELOG.md)
- [Commits](https://github.com/testing-library/react-testing-library/compare/v16.3.0...v16.3.1)

Updates `@typescript-eslint/eslint-plugin` from 8.48.1 to 8.49.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.49.0/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 8.48.1 to 8.49.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.49.0/packages/parser)

Updates `eslint` from 9.39.1 to 9.39.2
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/compare/v9.39.1...v9.39.2)

Updates `sass` from 1.94.2 to 1.96.0
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.94.2...1.96.0)

Updates `vite` from 7.2.7 to 7.3.0
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v7.3.0/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.3.0/packages/vite)

---
updated-dependencies:
- dependency-name: "@codemirror/view"
  dependency-version: 6.39.4
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: "@mantine/core"
  dependency-version: 8.3.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: "@mantine/hooks"
  dependency-version: 8.3.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: "@mantine/modals"
  dependency-version: 8.3.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: "@mantine/notifications"
  dependency-version: 8.3.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: "@tabler/icons-react"
  dependency-version: 3.36.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: react
  dependency-version: 19.2.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: react-dom
  dependency-version: 19.2.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: "@testing-library/react"
  dependency-version: 16.3.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.49.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.49.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: eslint
  dependency-version: 9.39.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: sass
  dependency-version: 1.96.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: vite
  dependency-version: 7.3.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 20:24:56 +00:00
b48103aa98 Merge pull request #109 from lordmathis/dependabot/npm_and_yarn/app/types/node-25.0.2
Bump @types/node from 24.10.1 to 25.0.2 in /app
2025-12-15 21:21:19 +01:00
dependabot[bot]
9489f3e880 Bump @types/node from 24.10.1 to 25.0.2 in /app
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.10.1 to 25.0.2.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 25.0.2
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 16:37:02 +00:00
853015a895 Merge pull request #106 from lordmathis/dependabot/npm_and_yarn/app/mdast-util-to-hast-13.2.1
Bump mdast-util-to-hast from 13.2.0 to 13.2.1 in /app
2025-12-08 19:35:25 +01:00
dependabot[bot]
ebf4480aec Bump mdast-util-to-hast from 13.2.0 to 13.2.1 in /app
Bumps [mdast-util-to-hast](https://github.com/syntax-tree/mdast-util-to-hast) from 13.2.0 to 13.2.1.
- [Release notes](https://github.com/syntax-tree/mdast-util-to-hast/releases)
- [Commits](https://github.com/syntax-tree/mdast-util-to-hast/compare/13.2.0...13.2.1)

---
updated-dependencies:
- dependency-name: mdast-util-to-hast
  dependency-version: 13.2.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-08 18:25:53 +00:00
8ab11d1c6d Merge pull request #105 from lordmathis/dependabot/npm_and_yarn/app/minor-and-patch-1dc092915c
Bump the minor-and-patch group in /app with 10 updates
2025-12-08 19:24:45 +01:00
dependabot[bot]
e1ca9096de Bump the minor-and-patch group in /app with 10 updates
Bumps the minor-and-patch group in /app with 10 updates:

| Package | From | To |
| --- | --- | --- |
| [react](https://github.com/facebook/react/tree/HEAD/packages/react) | `19.2.0` | `19.2.1` |
| [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) | `19.2.0` | `19.2.1` |
| [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) | `8.48.0` | `8.48.1` |
| [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) | `8.48.0` | `8.48.1` |
| [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react) | `5.1.1` | `5.1.2` |
| [@vitest/coverage-v8](https://github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8) | `4.0.14` | `4.0.15` |
| [jsdom](https://github.com/jsdom/jsdom) | `27.2.0` | `27.3.0` |
| [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) | `7.2.6` | `7.2.7` |
| [vite-plugin-compression2](https://github.com/nonzzz/vite-plugin-compression) | `2.3.1` | `2.4.0` |
| [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) | `4.0.14` | `4.0.15` |


Updates `react` from 19.2.0 to 19.2.1
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.1/packages/react)

Updates `react-dom` from 19.2.0 to 19.2.1
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.1/packages/react-dom)

Updates `@typescript-eslint/eslint-plugin` from 8.48.0 to 8.48.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.48.1/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 8.48.0 to 8.48.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.48.1/packages/parser)

Updates `@vitejs/plugin-react` from 5.1.1 to 5.1.2
- [Release notes](https://github.com/vitejs/vite-plugin-react/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-react/commits/plugin-react@5.1.2/packages/plugin-react)

Updates `@vitest/coverage-v8` from 4.0.14 to 4.0.15
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.15/packages/coverage-v8)

Updates `jsdom` from 27.2.0 to 27.3.0
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Changelog](https://github.com/jsdom/jsdom/blob/main/Changelog.md)
- [Commits](https://github.com/jsdom/jsdom/compare/27.2.0...27.3.0)

Updates `vite` from 7.2.6 to 7.2.7
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v7.2.7/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.2.7/packages/vite)

Updates `vite-plugin-compression2` from 2.3.1 to 2.4.0
- [Release notes](https://github.com/nonzzz/vite-plugin-compression/releases)
- [Changelog](https://github.com/nonzzz/vite-plugin-compression/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nonzzz/vite-plugin-compression/compare/v2.3.1...v2.4.0)

Updates `vitest` from 4.0.14 to 4.0.15
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.15/packages/vitest)

---
updated-dependencies:
- dependency-name: react
  dependency-version: 19.2.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: react-dom
  dependency-version: 19.2.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.48.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.48.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: "@vitejs/plugin-react"
  dependency-version: 5.1.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: "@vitest/coverage-v8"
  dependency-version: 4.0.15
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: jsdom
  dependency-version: 27.3.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: vite
  dependency-version: 7.2.7
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: vite-plugin-compression2
  dependency-version: 2.4.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: vitest
  dependency-version: 4.0.15
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-08 16:36:25 +00:00
92b4fcd5d9 Merge pull request #104 from lordmathis/dependabot/go_modules/server/minor-and-patch-e27c97ce28
Bump github.com/golang-migrate/migrate/v4 from 4.19.0 to 4.19.1 in /server in the minor-and-patch group
2025-12-02 09:25:11 +01:00
dependabot[bot]
8d7188c88d Bump github.com/golang-migrate/migrate/v4
Bumps the minor-and-patch group in /server with 1 update: [github.com/golang-migrate/migrate/v4](https://github.com/golang-migrate/migrate).


Updates `github.com/golang-migrate/migrate/v4` from 4.19.0 to 4.19.1
- [Release notes](https://github.com/golang-migrate/migrate/releases)
- [Commits](https://github.com/golang-migrate/migrate/compare/v4.19.0...v4.19.1)

---
updated-dependencies:
- dependency-name: github.com/golang-migrate/migrate/v4
  dependency-version: 4.19.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-02 06:33:59 +00:00
ff49954003 Merge pull request #103 from lordmathis/dependabot/npm_and_yarn/app/minor-and-patch-366619d8bb
Bump the minor-and-patch group in /app with 3 updates
2025-12-02 06:54:26 +01:00
dependabot[bot]
a8dad80538 Bump the minor-and-patch group in /app with 3 updates
Bumps the minor-and-patch group in /app with 3 updates: [@vitest/coverage-v8](https://github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8), [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) and [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest).


Updates `@vitest/coverage-v8` from 4.0.13 to 4.0.14
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.14/packages/coverage-v8)

Updates `vite` from 7.2.4 to 7.2.6
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.2.6/packages/vite)

Updates `vitest` from 4.0.13 to 4.0.14
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.14/packages/vitest)

---
updated-dependencies:
- dependency-name: "@vitest/coverage-v8"
  dependency-version: 4.0.14
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: vite
  dependency-version: 7.2.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: vitest
  dependency-version: 4.0.14
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-01 20:08:12 +00:00
63c1950186 Merge pull request #98 from lordmathis/dependabot/go_modules/server/minor-and-patch-6c3756ade3
Bump github.com/go-git/go-git/v5 from 5.16.3 to 5.16.4 in /server in the minor-and-patch group
2025-11-25 07:22:05 +01:00
dependabot[bot]
d51dfbb435 Bump github.com/go-git/go-git/v5 in /server in the minor-and-patch group
Bumps the minor-and-patch group in /server with 1 update: [github.com/go-git/go-git/v5](https://github.com/go-git/go-git).


Updates `github.com/go-git/go-git/v5` from 5.16.3 to 5.16.4
- [Release notes](https://github.com/go-git/go-git/releases)
- [Commits](https://github.com/go-git/go-git/compare/v5.16.3...v5.16.4)

---
updated-dependencies:
- dependency-name: github.com/go-git/go-git/v5
  dependency-version: 5.16.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-24 22:07:15 +00:00
1f74284773 Merge pull request #101 from lordmathis/dependabot/npm_and_yarn/app/jsdom-27.2.0
Bump jsdom from 26.1.0 to 27.2.0 in /app
2025-11-24 23:05:16 +01:00
dependabot[bot]
623c3843e4 Bump jsdom from 26.1.0 to 27.2.0 in /app
Bumps [jsdom](https://github.com/jsdom/jsdom) from 26.1.0 to 27.2.0.
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Changelog](https://github.com/jsdom/jsdom/blob/main/Changelog.md)
- [Commits](https://github.com/jsdom/jsdom/compare/26.1.0...27.2.0)

---
updated-dependencies:
- dependency-name: jsdom
  dependency-version: 27.2.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-24 21:58:58 +00:00
34916dc6ad Merge pull request #102 from lordmathis/dependabot/npm_and_yarn/app/eslint/compat-2.0.0
Bump @eslint/compat from 1.4.1 to 2.0.0 in /app
2025-11-24 22:57:48 +01:00
dependabot[bot]
37bc1035d3 Bump @eslint/compat from 1.4.1 to 2.0.0 in /app
Bumps [@eslint/compat](https://github.com/eslint/rewrite/tree/HEAD/packages/compat) from 1.4.1 to 2.0.0.
- [Release notes](https://github.com/eslint/rewrite/releases)
- [Changelog](https://github.com/eslint/rewrite/blob/main/packages/compat/CHANGELOG.md)
- [Commits](https://github.com/eslint/rewrite/commits/compat-v2.0.0/packages/compat)

---
updated-dependencies:
- dependency-name: "@eslint/compat"
  dependency-version: 2.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-24 21:50:19 +00:00
8678e2a12d Merge pull request #100 from lordmathis/dependabot/npm_and_yarn/app/vite-7.2.4
Bump vite from 6.4.1 to 7.2.4 in /app
2025-11-24 22:49:11 +01:00
f94885482a Merge branch 'main' into dependabot/npm_and_yarn/app/vite-7.2.4 2025-11-24 22:39:12 +01:00
6d5eab9f57 Merge pull request #99 from lordmathis/dependabot/npm_and_yarn/app/minor-and-patch-0c7067eb9a
Bump the minor-and-patch group in /app with 12 updates
2025-11-24 22:38:47 +01:00
dependabot[bot]
fbe44844a5 Bump vite from 6.4.1 to 7.2.4 in /app
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 6.4.1 to 7.2.4.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.2.4/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 7.2.4
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-24 18:38:16 +00:00
dependabot[bot]
52075d1756 Bump the minor-and-patch group in /app with 12 updates
Bumps the minor-and-patch group in /app with 12 updates:

| Package | From | To |
| --- | --- | --- |
| [@codemirror/autocomplete](https://github.com/codemirror/autocomplete) | `6.19.1` | `6.20.0` |
| [@codemirror/view](https://github.com/codemirror/view) | `6.38.6` | `6.38.8` |
| [@mantine/core](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/core) | `8.3.7` | `8.3.9` |
| [@mantine/hooks](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/hooks) | `8.3.7` | `8.3.9` |
| [@mantine/modals](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/modals) | `8.3.7` | `8.3.9` |
| [@mantine/notifications](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/notifications) | `8.3.7` | `8.3.9` |
| [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) | `19.2.5` | `19.2.7` |
| [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) | `8.46.4` | `8.48.0` |
| [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) | `8.46.4` | `8.48.0` |
| [@vitest/coverage-v8](https://github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8) | `4.0.8` | `4.0.13` |
| [sass](https://github.com/sass/dart-sass) | `1.94.0` | `1.94.2` |
| [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) | `4.0.8` | `4.0.13` |


Updates `@codemirror/autocomplete` from 6.19.1 to 6.20.0
- [Changelog](https://github.com/codemirror/autocomplete/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/autocomplete/compare/6.19.1...6.20.0)

Updates `@codemirror/view` from 6.38.6 to 6.38.8
- [Changelog](https://github.com/codemirror/view/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/view/compare/6.38.6...6.38.8)

Updates `@mantine/core` from 8.3.7 to 8.3.9
- [Release notes](https://github.com/mantinedev/mantine/releases)
- [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mantinedev/mantine/commits/8.3.9/packages/@mantine/core)

Updates `@mantine/hooks` from 8.3.7 to 8.3.9
- [Release notes](https://github.com/mantinedev/mantine/releases)
- [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mantinedev/mantine/commits/8.3.9/packages/@mantine/hooks)

Updates `@mantine/modals` from 8.3.7 to 8.3.9
- [Release notes](https://github.com/mantinedev/mantine/releases)
- [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mantinedev/mantine/commits/8.3.9/packages/@mantine/modals)

Updates `@mantine/notifications` from 8.3.7 to 8.3.9
- [Release notes](https://github.com/mantinedev/mantine/releases)
- [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mantinedev/mantine/commits/8.3.9/packages/@mantine/notifications)

Updates `@types/react` from 19.2.5 to 19.2.7
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `@typescript-eslint/eslint-plugin` from 8.46.4 to 8.48.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.48.0/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 8.46.4 to 8.48.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.48.0/packages/parser)

Updates `@vitest/coverage-v8` from 4.0.8 to 4.0.13
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.13/packages/coverage-v8)

Updates `sass` from 1.94.0 to 1.94.2
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.94.0...1.94.2)

Updates `vitest` from 4.0.8 to 4.0.13
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.13/packages/vitest)

---
updated-dependencies:
- dependency-name: "@codemirror/autocomplete"
  dependency-version: 6.20.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: "@codemirror/view"
  dependency-version: 6.38.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: "@mantine/core"
  dependency-version: 8.3.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: "@mantine/hooks"
  dependency-version: 8.3.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: "@mantine/modals"
  dependency-version: 8.3.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: "@mantine/notifications"
  dependency-version: 8.3.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: "@types/react"
  dependency-version: 19.2.7
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.48.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.48.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: "@vitest/coverage-v8"
  dependency-version: 4.0.13
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: sass
  dependency-version: 1.94.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: vitest
  dependency-version: 4.0.13
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-24 18:38:05 +00:00
35c4ede667 Merge pull request #97 from lordmathis/dependabot/go_modules/server/golang.org/x/crypto-0.45.0
Bump golang.org/x/crypto from 0.42.0 to 0.45.0 in /server
2025-11-20 09:19:50 +01:00
dependabot[bot]
6539579812 Bump golang.org/x/crypto from 0.42.0 to 0.45.0 in /server
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.42.0 to 0.45.0.
- [Commits](https://github.com/golang/crypto/compare/v0.42.0...v0.45.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.45.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-20 02:43:13 +00:00
d9f1a16d94 Merge pull request #96 from lordmathis/chore/update-deps
Bump React and TypeScript types
2025-11-15 15:21:49 +01:00
0999fa9315 Fix FileTree tests with async rendering and mock resize observer 2025-11-15 15:16:19 +01:00
cc8c8fd414 Fix typescript issues 2025-11-15 14:56:48 +01:00
9ba37b3342 Update react dependencies 2025-11-15 14:47:13 +01:00
140ccd6879 Bump React and TypeScript types 2025-11-15 01:19:01 +01:00
7424ce4385 Merge pull request #91 from lordmathis/dependabot/npm_and_yarn/app/minor-and-patch-5c01766afc
Bump sass from 1.93.3 to 1.94.0 in /app in the minor-and-patch group
2025-11-12 22:09:24 +01:00
c998800990 Merge branch 'main' into dependabot/npm_and_yarn/app/minor-and-patch-5c01766afc 2025-11-12 22:04:46 +01:00
c86d627053 Merge pull request #94 from lordmathis/dependabot/npm_and_yarn/app/types/node-24.10.1
Bump @types/node from 22.14.0 to 24.10.1 in /app
2025-11-12 22:04:31 +01:00
dependabot[bot]
5837cf7316 Bump @types/node from 22.14.0 to 24.10.1 in /app
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.14.0 to 24.10.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.10.1
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-12 20:57:11 +00:00
92a3dcdab7 Merge pull request #95 from lordmathis/dependabot/npm_and_yarn/app/vitejs/plugin-react-5.1.1
Bump @vitejs/plugin-react from 4.3.4 to 5.1.1 in /app
2025-11-12 21:55:57 +01:00
857b56fec2 Merge branch 'main' into dependabot/npm_and_yarn/app/vitejs/plugin-react-5.1.1 2025-11-12 21:51:41 +01:00
7e48ec935c Merge pull request #93 from lordmathis/dependabot/npm_and_yarn/app/eslint-plugin-react-hooks-7.0.1
Bump eslint-plugin-react-hooks from 5.2.0 to 7.0.1 in /app
2025-11-12 21:51:27 +01:00
b728c240b6 Merge branch 'main' into dependabot/npm_and_yarn/app/minor-and-patch-5c01766afc 2025-11-12 21:51:06 +01:00
e9aa611a41 Merge branch 'main' into dependabot/npm_and_yarn/app/eslint-plugin-react-hooks-7.0.1 2025-11-12 21:46:26 +01:00
441c31eb14 Merge branch 'main' into dependabot/npm_and_yarn/app/vitejs/plugin-react-5.1.1 2025-11-12 21:44:27 +01:00
fd75d6f8a0 Merge pull request #90 from lordmathis/dependabot/go_modules/server/minor-and-patch-2860a76c8c
Bump the minor-and-patch group in /server with 11 updates
2025-11-12 21:43:44 +01:00
dependabot[bot]
f54852bbad Bump @vitejs/plugin-react from 4.3.4 to 5.1.1 in /app
Bumps [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react) from 4.3.4 to 5.1.1.
- [Release notes](https://github.com/vitejs/vite-plugin-react/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-react/commits/plugin-react@5.1.1/packages/plugin-react)

---
updated-dependencies:
- dependency-name: "@vitejs/plugin-react"
  dependency-version: 5.1.1
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-12 20:37:13 +00:00
dependabot[bot]
9101acd171 Bump eslint-plugin-react-hooks from 5.2.0 to 7.0.1 in /app
Bumps [eslint-plugin-react-hooks](https://github.com/facebook/react/tree/HEAD/packages/eslint-plugin-react-hooks) from 5.2.0 to 7.0.1.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/packages/eslint-plugin-react-hooks/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/HEAD/packages/eslint-plugin-react-hooks)

---
updated-dependencies:
- dependency-name: eslint-plugin-react-hooks
  dependency-version: 7.0.1
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-12 20:36:49 +00:00
dependabot[bot]
d9a26830ff Bump sass from 1.93.3 to 1.94.0 in /app in the minor-and-patch group
Bumps the minor-and-patch group in /app with 1 update: [sass](https://github.com/sass/dart-sass).


Updates `sass` from 1.93.3 to 1.94.0
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.93.3...1.94.0)

---
updated-dependencies:
- dependency-name: sass
  dependency-version: 1.94.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-12 20:36:23 +00:00
dependabot[bot]
c095c4a049 Bump the minor-and-patch group in /server with 11 updates
Bumps the minor-and-patch group in /server with 11 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/go-chi/chi/v5](https://github.com/go-chi/chi) | `5.2.2` | `5.2.3` |
| [github.com/go-chi/cors](https://github.com/go-chi/cors) | `1.2.1` | `1.2.2` |
| [github.com/go-chi/httprate](https://github.com/go-chi/httprate) | `0.14.1` | `0.15.0` |
| [github.com/go-git/go-git/v5](https://github.com/go-git/go-git) | `5.13.1` | `5.16.3` |
| [github.com/go-playground/validator/v10](https://github.com/go-playground/validator) | `10.22.1` | `10.28.0` |
| [github.com/golang-jwt/jwt/v5](https://github.com/golang-jwt/jwt) | `5.2.2` | `5.3.0` |
| [github.com/golang-migrate/migrate/v4](https://github.com/golang-migrate/migrate) | `4.18.2` | `4.19.0` |
| [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) | `1.14.23` | `1.14.32` |
| [github.com/stretchr/testify](https://github.com/stretchr/testify) | `1.10.0` | `1.11.1` |
| [github.com/swaggo/swag](https://github.com/swaggo/swag) | `1.16.4` | `1.16.6` |
| [golang.org/x/crypto](https://github.com/golang/crypto) | `0.36.0` | `0.42.0` |


Updates `github.com/go-chi/chi/v5` from 5.2.2 to 5.2.3
- [Release notes](https://github.com/go-chi/chi/releases)
- [Changelog](https://github.com/go-chi/chi/blob/master/CHANGELOG.md)
- [Commits](https://github.com/go-chi/chi/compare/v5.2.2...v5.2.3)

Updates `github.com/go-chi/cors` from 1.2.1 to 1.2.2
- [Release notes](https://github.com/go-chi/cors/releases)
- [Commits](https://github.com/go-chi/cors/compare/v1.2.1...v1.2.2)

Updates `github.com/go-chi/httprate` from 0.14.1 to 0.15.0
- [Release notes](https://github.com/go-chi/httprate/releases)
- [Commits](https://github.com/go-chi/httprate/compare/v0.14.1...v0.15.0)

Updates `github.com/go-git/go-git/v5` from 5.13.1 to 5.16.3
- [Release notes](https://github.com/go-git/go-git/releases)
- [Commits](https://github.com/go-git/go-git/compare/v5.13.1...v5.16.3)

Updates `github.com/go-playground/validator/v10` from 10.22.1 to 10.28.0
- [Release notes](https://github.com/go-playground/validator/releases)
- [Commits](https://github.com/go-playground/validator/compare/v10.22.1...v10.28.0)

Updates `github.com/golang-jwt/jwt/v5` from 5.2.2 to 5.3.0
- [Release notes](https://github.com/golang-jwt/jwt/releases)
- [Changelog](https://github.com/golang-jwt/jwt/blob/main/VERSION_HISTORY.md)
- [Commits](https://github.com/golang-jwt/jwt/compare/v5.2.2...v5.3.0)

Updates `github.com/golang-migrate/migrate/v4` from 4.18.2 to 4.19.0
- [Release notes](https://github.com/golang-migrate/migrate/releases)
- [Changelog](https://github.com/golang-migrate/migrate/blob/master/.goreleaser.yml)
- [Commits](https://github.com/golang-migrate/migrate/compare/v4.18.2...v4.19.0)

Updates `github.com/mattn/go-sqlite3` from 1.14.23 to 1.14.32
- [Release notes](https://github.com/mattn/go-sqlite3/releases)
- [Commits](https://github.com/mattn/go-sqlite3/compare/v1.14.23...v1.14.32)

Updates `github.com/stretchr/testify` from 1.10.0 to 1.11.1
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.10.0...v1.11.1)

Updates `github.com/swaggo/swag` from 1.16.4 to 1.16.6
- [Release notes](https://github.com/swaggo/swag/releases)
- [Changelog](https://github.com/swaggo/swag/blob/master/.goreleaser.yml)
- [Commits](https://github.com/swaggo/swag/compare/v1.16.4...v1.16.6)

Updates `golang.org/x/crypto` from 0.36.0 to 0.42.0
- [Commits](https://github.com/golang/crypto/compare/v0.36.0...v0.42.0)

---
updated-dependencies:
- dependency-name: github.com/go-chi/chi/v5
  dependency-version: 5.2.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: github.com/go-chi/cors
  dependency-version: 1.2.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: github.com/go-chi/httprate
  dependency-version: 0.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: github.com/go-git/go-git/v5
  dependency-version: 5.16.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: github.com/go-playground/validator/v10
  dependency-version: 10.28.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: github.com/golang-jwt/jwt/v5
  dependency-version: 5.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: github.com/golang-migrate/migrate/v4
  dependency-version: 4.19.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: github.com/mattn/go-sqlite3
  dependency-version: 1.14.32
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: github.com/stretchr/testify
  dependency-version: 1.11.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: github.com/swaggo/swag
  dependency-version: 1.16.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: golang.org/x/crypto
  dependency-version: 0.42.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-12 20:36:07 +00:00
728367a6f6 Merge pull request #89 from lordmathis/lordmathis-patch-1
Update dependabot.yml
2025-11-12 21:34:42 +01:00
dd854b755e Update dependabot.yml 2025-11-12 21:31:27 +01:00
7dd8e3c763 Merge pull request #88 from lordmathis/docs/screenshot
Add app screenshot to README
2025-11-12 18:52:23 +01:00
0c3847241b Add app screenshot to README 2025-11-12 18:46:43 +01:00
9a8f2e8a46 Merge pull request #87 from lordmathis/fix/default-file-text
Update default file content to reflect project name change
2025-11-12 18:30:48 +01:00
914f9a68f4 Update default file content to reflect project name change 2025-11-12 18:27:09 +01:00
33c93e40d1 Merge pull request #86 from lordmathis/docs/readme-update
Update README
2025-11-11 22:40:54 +01:00
aace38d1a0 Improve README features section 2025-11-11 22:24:46 +01:00
71bd791c60 Update environment variable configuration section in README 2025-11-11 22:18:44 +01:00
74aeeec42b Merge pull request #85 from lordmathis/feat/wikilinks-autocomplete
Add autocompletion for wiki links
2025-11-11 22:05:57 +01:00
2e7bd88a57 Add autocompletion for wiki links 2025-11-11 21:56:18 +01:00
0579b8d0e5 Merge pull request #84 from lordmathis/feat/new-file-folder
Improve create file modal with parent folder selection
2025-11-11 20:41:51 +01:00
93f484eb91 Close folder selection popover after selecting a folder in CreateFileModal 2025-11-11 20:11:51 +01:00
bc49391b5c Add FolderSelector component and integrate with CreateFileModal 2025-11-11 20:05:27 +01:00
25 changed files with 2178 additions and 1263 deletions

View File

@@ -11,7 +11,7 @@ updates:
- "patch"
- package-ecosystem: "gomod"
directory: "/"
directory: "/server"
schedule:
interval: "weekly"
groups:

BIN
.github/screenshot.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

5
.gitignore vendored
View File

@@ -164,4 +164,7 @@ main
data
# Feature specifications
spec.md
spec.md
# Go debug files
__debug_bin*

View File

@@ -4,15 +4,21 @@
Yet another markdown editor. Work in progress
![App Screenshot](./.github/screenshot.png)
## Features
- Markdown editing with syntax highlighting
- File tree navigation
- Git integration for version control
- Dark and light theme support
- Multiple workspaces
- Math equation support (MathJax)
- Code syntax highlighting
- **Editing & Content**
- **Rich Markdown Editing** - Full-featured editor with syntax highlighting and live preview
- **Wikilinks Support** - Create interconnected notes with `[[wikilink]]` syntax and smart autocomplete
- **Math Equations** - Render beautiful mathematical expressions with MathJax support
- **Code Highlighting** - Syntax highlighting for code blocks in multiple languages
- **Organization & Workflow**
- **File Tree Navigation** - Organized folder structure with intuitive file management
- **Multi-Workspace** - Manage multiple projects and note collections in one place
- **Git Integration** - Built-in version control to track changes and collaborate safely
- **Customization**
- **Theme Flexibility** - Switch between dark and light modes to match your preference
## Prerequisites
@@ -22,33 +28,32 @@ Yet another markdown editor. Work in progress
## Configuration
Lemma can be configured using environment variables. Here are the available configuration options:
Lemma is configured using environment variables.
### Required Environment Variables
### Environment Variables
- `LEMMA_ADMIN_EMAIL`: Email address for the admin account
- `LEMMA_ADMIN_PASSWORD`: Password for the admin account
### Optional Environment Variables
- `LEMMA_ENV`: Set to "development" to enable development mode
- `LEMMA_DB_URL`: URL (Connection string) to the database. Supported databases are sqlite and postgres a (default: "./lemma.db")
- `LEMMA_WORKDIR`: Working directory for application data (default: "sqlite://lemma.db")
- `LEMMA_STATIC_PATH`: Path to static files (default: "../app/dist")
- `LEMMA_PORT`: Port to run the server on (default: "8080")
- `LEMMA_DOMAIN`: Domain name where the application is hosted for cookie authentication
- `LEMMA_CORS_ORIGINS`: Comma-separated list of allowed CORS origins
- `LEMMA_ENCRYPTION_KEY`: Base64-encoded 32-byte key used for encrypting sensitive data. If not provided, a key will be automatically generated and stored in `{LEMMA_WORKDIR}/secrets/encryption_key`
- `LEMMA_JWT_SIGNING_KEY`: Key used for signing JWT tokens. If not provided, a key will be automatically generated and stored in `{LEMMA_WORKDIR}/secrets/jwt_signing_key`
- `LEMMA_LOG_LEVEL`: Logging level (defaults to DEBUG in development mode, INFO in production)
- `LEMMA_RATE_LIMIT_REQUESTS`: Number of allowed requests per window (default: 100)
- `LEMMA_RATE_LIMIT_WINDOW`: Duration of the rate limit window (default: 15m)
| Variable | Required | Default | Description |
| --------------------------- | -------- | ------------------- | -------------------------------------------------------------------------------------------------------- |
| `LEMMA_ADMIN_EMAIL` | Yes | - | Email address for the admin account |
| `LEMMA_ADMIN_PASSWORD` | Yes | - | Password for the admin account |
| `LEMMA_ENV` | No | production | Set to "development" to enable development mode |
| `LEMMA_DB_URL` | No | `sqlite://lemma.db` | Database connection string (supports `sqlite://`, `sqlite3://`, `postgres://`, `postgresql://` prefixes) |
| `LEMMA_WORKDIR` | No | `./data` | Working directory for application data |
| `LEMMA_STATIC_PATH` | No | `../app/dist` | Path to static files |
| `LEMMA_PORT` | No | `8080` | Port to run the server on |
| `LEMMA_DOMAIN` | No | - | Domain name for cookie authentication |
| `LEMMA_CORS_ORIGINS` | No | - | Comma-separated list of allowed CORS origins |
| `LEMMA_ENCRYPTION_KEY` | No | auto-generated | Base64-encoded 32-byte key for encrypting sensitive data |
| `LEMMA_JWT_SIGNING_KEY` | No | auto-generated | Key used for signing JWT tokens |
| `LEMMA_LOG_LEVEL` | No | DEBUG/INFO\* | Logging level (\*DEBUG in dev, INFO in production) |
| `LEMMA_RATE_LIMIT_REQUESTS` | No | `100` | Number of allowed requests per window |
| `LEMMA_RATE_LIMIT_WINDOW` | No | `15m` | Duration of the rate limit window |
### Security Keys
Both the encryption key and JWT signing key are automatically generated on first startup if not provided via environment variables. The keys are stored in `{LEMMA_WORKDIR}/secrets/` with restrictive file permissions (0600).
Security keys (`LEMMA_ENCRYPTION_KEY` and `LEMMA_JWT_SIGNING_KEY`) are automatically generated on first startup if not provided. Keys are stored in `{LEMMA_WORKDIR}/secrets/`.
**Important**: Back up the `secrets` directory! If these keys are lost, encrypted data will become inaccessible and all users will need to re-authenticate.
**Important:** Back up the `secrets` directory!
## Running the backend server

2059
app/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -29,21 +29,23 @@
},
"homepage": "https://github.com/LordMathis/Lemma#readme",
"dependencies": {
"@codemirror/commands": "^6.10.0",
"@codemirror/autocomplete": "^6.20.0",
"@codemirror/commands": "^6.10.1",
"@codemirror/lang-markdown": "^6.5.0",
"@codemirror/state": "^6.5.2",
"@codemirror/state": "^6.5.3",
"@codemirror/theme-one-dark": "^6.1.3",
"@codemirror/view": "^6.38.6",
"@mantine/core": "^8.3.7",
"@mantine/hooks": "^8.3.7",
"@mantine/modals": "^8.3.7",
"@mantine/notifications": "^8.3.7",
"@codemirror/view": "^6.39.5",
"@floating-ui/react": "^0.27.16",
"@mantine/core": "^8.3.10",
"@mantine/hooks": "^8.3.10",
"@mantine/modals": "^8.3.10",
"@mantine/notifications": "^8.3.10",
"@react-hook/resize-observer": "^2.0.2",
"@tabler/icons-react": "^3.35.0",
"@tabler/icons-react": "^3.36.0",
"codemirror": "^6.0.2",
"react": "^18.3.1",
"react": "^19.2.3",
"react-arborist": "^3.4.3",
"react-dom": "^18.3.1",
"react-dom": "^19.2.3",
"rehype-highlight": "^7.0.2",
"rehype-mathjax": "^7.1.0",
"rehype-react": "^8.0.0",
@@ -55,28 +57,28 @@
"unist-util-visit": "^5.0.0"
},
"devDependencies": {
"@eslint/compat": "^1.4.1",
"@eslint/compat": "^2.0.0",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.0",
"@testing-library/react": "^16.3.1",
"@types/babel__core": "^7.20.5",
"@types/node": "^22.14.0",
"@types/react": "^18.3.20",
"@types/react-dom": "^18.3.6",
"@typescript-eslint/eslint-plugin": "^8.46.4",
"@types/node": "^25.0.3",
"@types/react": "^19.2.7",
"@types/react-dom": "^19.2.3",
"@typescript-eslint/eslint-plugin": "^8.50.0",
"@typescript-eslint/parser": "^8.32.1",
"@vitejs/plugin-react": "^4.3.4",
"@vitest/coverage-v8": "^4.0.8",
"eslint": "^9.39.1",
"@vitejs/plugin-react": "^5.1.2",
"@vitest/coverage-v8": "^4.0.16",
"eslint": "^9.39.2",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^5.2.0",
"jsdom": "^26.1.0",
"eslint-plugin-react-hooks": "^7.0.1",
"jsdom": "^27.3.0",
"postcss": "^8.5.6",
"postcss-preset-mantine": "^1.18.0",
"postcss-simple-vars": "^7.0.1",
"sass": "^1.93.3",
"sass": "^1.97.1",
"typescript": "^5.9.3",
"vite": "^6.4.1",
"vite-plugin-compression2": "^2.3.1",
"vite": "^7.3.0",
"vite-plugin-compression2": "^2.4.0",
"vitest": "^4.0.8"
},
"browserslist": {

View File

@@ -104,6 +104,7 @@ describe('ContentView', () => {
handleContentChange={mockHandleContentChange}
handleSave={mockHandleSave}
handleFileSelect={mockHandleFileSelect}
files={[]}
/>
</TestWrapper>
);
@@ -121,6 +122,7 @@ describe('ContentView', () => {
handleContentChange={mockHandleContentChange}
handleSave={mockHandleSave}
handleFileSelect={mockHandleFileSelect}
files={[]}
/>
</TestWrapper>
);
@@ -138,6 +140,7 @@ describe('ContentView', () => {
handleContentChange={mockHandleContentChange}
handleSave={mockHandleSave}
handleFileSelect={mockHandleFileSelect}
files={[]}
/>
</TestWrapper>
);
@@ -157,6 +160,7 @@ describe('ContentView', () => {
handleContentChange={mockHandleContentChange}
handleSave={mockHandleSave}
handleFileSelect={mockHandleFileSelect}
files={[]}
/>
</TestWrapper>
);
@@ -179,6 +183,7 @@ describe('ContentView', () => {
handleContentChange={mockHandleContentChange}
handleSave={mockHandleSave}
handleFileSelect={mockHandleFileSelect}
files={[]}
/>
</TestWrapper>
);
@@ -208,6 +213,7 @@ describe('ContentView', () => {
handleContentChange={mockHandleContentChange}
handleSave={mockHandleSave}
handleFileSelect={mockHandleFileSelect}
files={[]}
/>
</TestWrapper>
);

View File

@@ -4,6 +4,7 @@ import Editor from './Editor';
import MarkdownPreview from './MarkdownPreview';
import { getFileUrl, isImageFile } from '../../utils/fileHelpers';
import { useWorkspace } from '@/contexts/WorkspaceContext';
import type { FileNode } from '../../types/models';
type ViewTab = 'source' | 'preview';
@@ -14,6 +15,7 @@ interface ContentViewProps {
handleContentChange: (content: string) => void;
handleSave: (filePath: string, content: string) => Promise<boolean>;
handleFileSelect: (filePath: string | null) => Promise<void>;
files: FileNode[];
}
const ContentView: React.FC<ContentViewProps> = ({
@@ -23,6 +25,7 @@ const ContentView: React.FC<ContentViewProps> = ({
handleContentChange,
handleSave,
handleFileSelect,
files,
}) => {
const { currentWorkspace } = useWorkspace();
if (!currentWorkspace) {
@@ -67,6 +70,7 @@ const ContentView: React.FC<ContentViewProps> = ({
handleContentChange={handleContentChange}
handleSave={handleSave}
selectedFile={selectedFile}
files={files}
/>
) : (
<MarkdownPreview content={content} handleFileSelect={handleFileSelect} />

View File

@@ -1,17 +1,22 @@
import React, { useEffect, useRef } from 'react';
import React, { useEffect, useRef, useMemo } from 'react';
import { basicSetup } from 'codemirror';
import { EditorState } from '@codemirror/state';
import { EditorView, keymap } from '@codemirror/view';
import { markdown } from '@codemirror/lang-markdown';
import { defaultKeymap } from '@codemirror/commands';
import { oneDark } from '@codemirror/theme-one-dark';
import { autocompletion } from '@codemirror/autocomplete';
import { useWorkspace } from '../../hooks/useWorkspace';
import { createWikiLinkCompletions } from '../../utils/wikiLinkCompletion';
import { flattenFileTree } from '../../utils/fileHelpers';
import type { FileNode } from '../../types/models';
interface EditorProps {
content: string;
handleContentChange: (content: string) => void;
handleSave: (filePath: string, content: string) => Promise<boolean>;
selectedFile: string;
files: FileNode[];
}
const Editor: React.FC<EditorProps> = ({
@@ -19,11 +24,19 @@ const Editor: React.FC<EditorProps> = ({
handleContentChange,
handleSave,
selectedFile,
files,
}) => {
const { colorScheme } = useWorkspace();
const { colorScheme, currentWorkspace } = useWorkspace();
const editorRef = useRef<HTMLDivElement>(null);
const viewRef = useRef<EditorView | null>(null);
// Flatten file tree for autocompletion, respecting showHiddenFiles setting
const showHiddenFiles = currentWorkspace?.showHiddenFiles || false;
const flatFiles = useMemo(
() => flattenFileTree(files, showHiddenFiles),
[files, showHiddenFiles]
);
useEffect(() => {
const handleEditorSave = (view: EditorView): boolean => {
void handleSave(selectedFile, view.state.doc.toString());
@@ -71,6 +84,12 @@ const Editor: React.FC<EditorProps> = ({
}),
theme,
colorScheme === 'dark' ? oneDark : [],
autocompletion({
override: [createWikiLinkCompletions(flatFiles)],
activateOnTyping: true,
maxRenderedOptions: 10,
closeOnBlur: true,
}),
],
});
@@ -87,7 +106,7 @@ const Editor: React.FC<EditorProps> = ({
};
// TODO: Refactor
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [colorScheme, handleContentChange, handleSave, selectedFile]);
}, [colorScheme, handleContentChange, handleSave, selectedFile, flatFiles]);
useEffect(() => {
if (viewRef.current && content !== viewRef.current.state.doc.toString()) {

View File

@@ -69,7 +69,19 @@ vi.mock('react-arborist', () => ({
// Mock resize observer hook
vi.mock('@react-hook/resize-observer', () => ({
default: vi.fn(),
default: vi.fn(
(
_target: unknown,
callback: (entry: { contentRect: { width: number; height: number } }) => void
) => {
// Immediately call the callback with a mock entry to provide size
if (callback) {
setTimeout(() => {
callback({ contentRect: { width: 300, height: 600 } });
}, 0);
}
}
),
}));
// Mock contexts
@@ -172,7 +184,7 @@ describe('FileTree', () => {
vi.clearAllMocks();
});
it('renders file tree with files', () => {
it('renders file tree with files', async () => {
const { getByTestId } = render(
<TestWrapper>
<FileTree
@@ -184,7 +196,9 @@ describe('FileTree', () => {
</TestWrapper>
);
expect(getByTestId('file-tree')).toBeInTheDocument();
await waitFor(() => {
expect(getByTestId('file-tree')).toBeInTheDocument();
});
expect(getByTestId('file-node-1')).toBeInTheDocument();
expect(getByTestId('file-node-2')).toBeInTheDocument();
});
@@ -201,6 +215,10 @@ describe('FileTree', () => {
</TestWrapper>
);
await waitFor(() => {
expect(getByTestId('file-node-1')).toBeInTheDocument();
});
const fileNode = getByTestId('file-node-1');
fireEvent.click(fileNode);
@@ -209,7 +227,7 @@ describe('FileTree', () => {
});
});
it('filters out hidden files when showHiddenFiles is false', () => {
it('filters out hidden files when showHiddenFiles is false', async () => {
const { getByTestId, queryByTestId } = render(
<TestWrapper>
<FileTree
@@ -221,6 +239,10 @@ describe('FileTree', () => {
</TestWrapper>
);
await waitFor(() => {
expect(getByTestId('file-node-1')).toBeInTheDocument();
});
// Should show regular files
expect(getByTestId('file-node-1')).toBeInTheDocument();
expect(getByTestId('file-node-2')).toBeInTheDocument();
@@ -229,7 +251,7 @@ describe('FileTree', () => {
expect(queryByTestId('file-node-4')).not.toBeInTheDocument();
});
it('shows hidden files when showHiddenFiles is true', () => {
it('shows hidden files when showHiddenFiles is true', async () => {
const { getByTestId } = render(
<TestWrapper>
<FileTree
@@ -241,13 +263,17 @@ describe('FileTree', () => {
</TestWrapper>
);
await waitFor(() => {
expect(getByTestId('file-node-1')).toBeInTheDocument();
});
// Should show all files including hidden
expect(getByTestId('file-node-1')).toBeInTheDocument();
expect(getByTestId('file-node-2')).toBeInTheDocument();
expect(getByTestId('file-node-4')).toBeInTheDocument();
});
it('renders empty tree when no files provided', () => {
it('renders empty tree when no files provided', async () => {
const { getByTestId } = render(
<TestWrapper>
<FileTree
@@ -259,6 +285,10 @@ describe('FileTree', () => {
</TestWrapper>
);
await waitFor(() => {
expect(getByTestId('file-tree')).toBeInTheDocument();
});
const tree = getByTestId('file-tree');
expect(tree).toBeInTheDocument();
expect(tree.children).toHaveLength(0);
@@ -276,6 +306,10 @@ describe('FileTree', () => {
</TestWrapper>
);
await waitFor(() => {
expect(getByTestId('file-node-2')).toBeInTheDocument();
});
// Click on folder (has children)
const folderNode = getByTestId('file-node-2');
fireEvent.click(folderNode);

View File

@@ -1,4 +1,4 @@
import React, { useRef, useState, useLayoutEffect, useCallback } from 'react';
import React, { useRef, useState, useCallback } from 'react';
import { Tree, type NodeApi } from 'react-arborist';
import {
IconFile,
@@ -23,15 +23,11 @@ interface FileTreeProps {
loadFileList: () => Promise<void>;
}
const useSize = (target: React.RefObject<HTMLElement>): Size | undefined => {
const useSize = (
target: React.RefObject<HTMLElement | null>
): Size | undefined => {
const [size, setSize] = useState<Size>();
useLayoutEffect(() => {
if (target.current) {
setSize(target.current.getBoundingClientRect());
}
}, [target]);
useResizeObserver(target, (entry) => setSize(entry.contentRect));
return size;
};

View File

@@ -0,0 +1,269 @@
import React, { useRef, useState } from 'react';
import { Box } from '@mantine/core';
import { Tree, type NodeApi } from 'react-arborist';
import {
IconFolder,
IconFolderOpen,
IconChevronRight,
} from '@tabler/icons-react';
import useResizeObserver from '@react-hook/resize-observer';
import { filterToFolders } from '../../utils/fileTreeUtils';
import type { FileNode } from '@/types/models';
interface FolderSelectorProps {
files: FileNode[];
selectedPath: string;
onSelect: (path: string) => void;
}
interface Size {
width: number;
height: number;
}
const useSize = (
target: React.RefObject<HTMLElement | null>
): Size | undefined => {
const [size, setSize] = useState<Size>();
useResizeObserver(target, (entry) => setSize(entry.contentRect));
return size;
};
// Node component for rendering folders
function FolderNode({
node,
style,
selectedPath,
onSelect,
}: {
node: NodeApi<FileNode>;
style: React.CSSProperties;
selectedPath: string;
onSelect: (path: string) => void;
}) {
const isSelected = node.data.path === selectedPath;
const hasChildren = node.children && node.children.length > 0;
const handleClick = () => {
onSelect(node.data.path);
};
const handleChevronClick = (e: React.MouseEvent) => {
e.stopPropagation();
node.toggle();
};
return (
<div
style={{
...style,
paddingLeft: `${node.level * 16 + 8}px`,
paddingRight: '8px',
paddingTop: '4px',
paddingBottom: '4px',
display: 'flex',
alignItems: 'center',
cursor: 'pointer',
whiteSpace: 'nowrap',
overflow: 'hidden',
backgroundColor: isSelected
? 'var(--mantine-color-blue-filled)'
: 'transparent',
color: isSelected ? 'var(--mantine-color-white)' : 'inherit',
borderRadius: '4px',
transition: 'background-color 0.1s ease, color 0.1s ease',
}}
onClick={handleClick}
title={node.data.name}
onMouseEnter={(e) => {
if (!isSelected) {
e.currentTarget.style.backgroundColor =
'var(--mantine-color-default-hover)';
}
}}
onMouseLeave={(e) => {
if (!isSelected) {
e.currentTarget.style.backgroundColor = 'transparent';
}
}}
>
{/* Chevron for folders with children */}
{hasChildren && (
<IconChevronRight
size={14}
onClick={handleChevronClick}
style={{
marginRight: '4px',
transform: node.isOpen ? 'rotate(90deg)' : 'rotate(0deg)',
transition: 'transform 0.2s ease',
flexShrink: 0,
}}
/>
)}
{/* Spacer for items without chevron */}
{!hasChildren && <div style={{ width: '18px', flexShrink: 0 }} />}
{/* Folder icon */}
{node.isOpen ? (
<IconFolderOpen
size={16}
color={
isSelected
? 'var(--mantine-color-white)'
: 'var(--mantine-color-yellow-filled)'
}
style={{ flexShrink: 0 }}
/>
) : (
<IconFolder
size={16}
color={
isSelected
? 'var(--mantine-color-white)'
: 'var(--mantine-color-yellow-filled)'
}
style={{ flexShrink: 0 }}
/>
)}
{/* Name */}
<span
style={{
marginLeft: '8px',
fontSize: '14px',
overflow: 'hidden',
textOverflow: 'ellipsis',
flexGrow: 1,
}}
>
{node.data.name}
</span>
</div>
);
}
// Root node component
function RootNode({
isSelected,
onSelect,
}: {
isSelected: boolean;
onSelect: () => void;
}) {
return (
<div
style={{
paddingLeft: '8px',
paddingRight: '8px',
paddingTop: '4px',
paddingBottom: '4px',
display: 'flex',
alignItems: 'center',
cursor: 'pointer',
whiteSpace: 'nowrap',
overflow: 'hidden',
backgroundColor: isSelected
? 'var(--mantine-color-blue-filled)'
: 'transparent',
color: isSelected ? 'var(--mantine-color-white)' : 'inherit',
borderRadius: '4px',
transition: 'background-color 0.1s ease, color 0.1s ease',
marginBottom: '4px',
}}
onClick={onSelect}
onMouseEnter={(e) => {
if (!isSelected) {
e.currentTarget.style.backgroundColor =
'var(--mantine-color-default-hover)';
}
}}
onMouseLeave={(e) => {
if (!isSelected) {
e.currentTarget.style.backgroundColor = 'transparent';
}
}}
>
<div style={{ width: '18px', flexShrink: 0 }} />
<IconFolder
size={16}
color={
isSelected
? 'var(--mantine-color-white)'
: 'var(--mantine-color-yellow-filled)'
}
style={{ flexShrink: 0 }}
/>
<span
style={{
marginLeft: '8px',
fontSize: '14px',
overflow: 'hidden',
textOverflow: 'ellipsis',
flexGrow: 1,
}}
>
/ (root)
</span>
</div>
);
}
export const FolderSelector: React.FC<FolderSelectorProps> = ({
files,
selectedPath,
onSelect,
}) => {
const target = useRef<HTMLDivElement>(null);
const size = useSize(target);
// Filter to only folders
const folders = filterToFolders(files);
// Calculate tree height: root node (32px) + folders
const rootNodeHeight = 32;
const treeHeight = size ? size.height - rootNodeHeight : 0;
return (
<Box
ref={target}
style={{
maxHeight: '300px',
height: '300px',
overflowY: 'auto',
padding: '8px',
}}
>
{/* Root option */}
<RootNode
isSelected={selectedPath === ''}
onSelect={() => onSelect('')}
/>
{/* Folder tree */}
{size && folders.length > 0 && (
<Tree
data={folders}
openByDefault={false}
width={size.width - 16}
height={treeHeight}
indent={24}
rowHeight={28}
idAccessor="id"
disableDrag={() => true}
disableDrop={() => true}
>
{(props) => (
<FolderNode
{...props}
selectedPath={selectedPath}
onSelect={onSelect}
/>
)}
</Tree>
)}
</Box>
);
};
export default FolderSelector;

View File

@@ -53,6 +53,7 @@ const Layout: React.FC = () => {
selectedFile={selectedFile}
handleFileSelect={handleFileSelect}
loadFileList={loadFileList}
files={files}
/>
</Container>
</AppShell.Main>

View File

@@ -131,6 +131,7 @@ describe('MainContent', () => {
selectedFile="docs/guide.md"
handleFileSelect={mockHandleFileSelect}
loadFileList={mockLoadFileList}
files={[]}
/>
</TestWrapper>
);
@@ -156,6 +157,7 @@ describe('MainContent', () => {
selectedFile="test.md"
handleFileSelect={mockHandleFileSelect}
loadFileList={mockLoadFileList}
files={[]}
/>
</TestWrapper>
);
@@ -172,6 +174,7 @@ describe('MainContent', () => {
selectedFile="test.md"
handleFileSelect={mockHandleFileSelect}
loadFileList={mockLoadFileList}
files={[]}
/>
</TestWrapper>
);
@@ -188,6 +191,7 @@ describe('MainContent', () => {
selectedFile={null}
handleFileSelect={mockHandleFileSelect}
loadFileList={mockLoadFileList}
files={[]}
/>
</TestWrapper>
);

View File

@@ -12,6 +12,7 @@ import { useFileContent } from '../../hooks/useFileContent';
import { useFileOperations } from '../../hooks/useFileOperations';
import { useGitOperations } from '../../hooks/useGitOperations';
import { useModalContext } from '../../contexts/ModalContext';
import type { FileNode } from '../../types/models';
type ViewTab = 'source' | 'preview';
@@ -19,12 +20,14 @@ interface MainContentProps {
selectedFile: string | null;
handleFileSelect: (filePath: string | null) => Promise<void>;
loadFileList: () => Promise<void>;
files: FileNode[];
}
const MainContent: React.FC<MainContentProps> = ({
selectedFile,
handleFileSelect,
loadFileList,
files,
}) => {
const [activeTab, setActiveTab] = useState<ViewTab>('source');
const {
@@ -161,6 +164,7 @@ const MainContent: React.FC<MainContentProps> = ({
handleContentChange={handleContentChange}
handleSave={handleSaveFile}
handleFileSelect={handleFileSelect}
files={files}
/>
</Box>
<CreateFileModal onCreateFile={handleCreateFile} />

View File

@@ -29,6 +29,31 @@ vi.mock('../../../contexts/ModalContext', () => ({
useModalContext: () => mockModalContext,
}));
// Mock useFileList hook
const mockLoadFileList = vi.fn();
const mockFiles = [
{
id: '1',
name: 'docs',
path: 'docs',
children: [
{
id: '2',
name: 'guides',
path: 'docs/guides',
children: [],
},
],
},
];
vi.mock('../../../hooks/useFileList', () => ({
useFileList: () => ({
files: mockFiles,
loadFileList: mockLoadFileList,
}),
}));
// Helper wrapper component for testing
const TestWrapper = ({ children }: { children: React.ReactNode }) => (
<MantineProvider defaultColorScheme="light">{children}</MantineProvider>
@@ -47,6 +72,8 @@ describe('CreateFileModal', () => {
mockOnCreateFile.mockReset();
mockOnCreateFile.mockResolvedValue(undefined);
mockModalContext.setNewFileModalVisible.mockClear();
mockLoadFileList.mockClear();
mockLoadFileList.mockResolvedValue(undefined);
});
describe('Modal Visibility and Content', () => {

View File

@@ -1,6 +1,9 @@
import React, { useState } from 'react';
import { Modal, TextInput, Button, Group, Box } from '@mantine/core';
import { Modal, TextInput, Button, Group, Box, Popover, ActionIcon, Text } from '@mantine/core';
import { IconFolderOpen } from '@tabler/icons-react';
import { useModalContext } from '../../../contexts/ModalContext';
import { useFileList } from '../../../hooks/useFileList';
import { FolderSelector } from '../../files/FolderSelector';
interface CreateFileModalProps {
onCreateFile: (fileName: string) => Promise<void>;
@@ -8,16 +11,49 @@ interface CreateFileModalProps {
const CreateFileModal: React.FC<CreateFileModalProps> = ({ onCreateFile }) => {
const [fileName, setFileName] = useState<string>('');
const [selectedFolder, setSelectedFolder] = useState<string>('');
const [popoverOpened, setPopoverOpened] = useState<boolean>(false);
const { newFileModalVisible, setNewFileModalVisible } = useModalContext();
const { files, loadFileList } = useFileList();
const handleSubmit = async (): Promise<void> => {
if (fileName) {
await onCreateFile(fileName.trim());
const fullPath = selectedFolder
? `${selectedFolder}/${fileName.trim()}`
: fileName.trim();
await onCreateFile(fullPath);
setFileName('');
setSelectedFolder('');
setNewFileModalVisible(false);
}
};
const handleClose = () => {
setFileName('');
setSelectedFolder('');
setNewFileModalVisible(false);
};
const handleFolderSelect = (path: string) => {
setSelectedFolder(path);
setPopoverOpened(false);
};
// Load files when modal opens
React.useEffect(() => {
if (newFileModalVisible) {
void loadFileList();
}
}, [newFileModalVisible, loadFileList]);
// Generate full path preview
const fullPathPreview = selectedFolder
? `${selectedFolder}/${fileName || 'filename'}`
: fileName || 'filename';
// Display text for location input
const locationDisplay = selectedFolder || '/ (root)';
const handleKeyDown = (event: React.KeyboardEvent): void => {
if (event.key === 'Enter' && !event.shiftKey) {
event.preventDefault();
@@ -28,27 +64,82 @@ const CreateFileModal: React.FC<CreateFileModalProps> = ({ onCreateFile }) => {
return (
<Modal
opened={newFileModalVisible}
onClose={() => setNewFileModalVisible(false)}
onClose={handleClose}
title="Create New File"
centered
size="sm"
>
<Box maw={400} mx="auto">
{/* Location input with folder picker */}
<Popover
opened={popoverOpened}
onChange={setPopoverOpened}
position="bottom-start"
width="target"
>
<Popover.Target>
<TextInput
label="Location"
type="text"
placeholder="Select folder"
data-testid="location-input"
value={locationDisplay}
readOnly
mb="md"
w="100%"
rightSection={
<ActionIcon
variant="subtle"
onClick={() => setPopoverOpened((o) => !o)}
data-testid="folder-picker-button"
>
<IconFolderOpen size={18} />
</ActionIcon>
}
styles={{
input: {
cursor: 'pointer',
},
}}
onClick={() => setPopoverOpened(true)}
/>
</Popover.Target>
<Popover.Dropdown>
<FolderSelector
files={files}
selectedPath={selectedFolder}
onSelect={handleFolderSelect}
/>
</Popover.Dropdown>
</Popover>
{/* File name input */}
<TextInput
label="File Name"
type="text"
placeholder="Enter file name"
placeholder="example.md"
data-testid="file-name-input"
value={fileName}
onChange={(event) => setFileName(event.currentTarget.value)}
onKeyDown={handleKeyDown}
mb="md"
mb="xs"
w="100%"
/>
{/* Hint text */}
<Text size="xs" c="dimmed" mb="xs">
Tip: Use / to create nested folders (e.g., folder/subfolder/file.md)
</Text>
{/* Full path preview */}
<Text size="sm" c="dimmed" mb="md">
Full path: {fullPathPreview}
</Text>
<Group justify="flex-end" mt="md">
<Button
variant="default"
onClick={() => setNewFileModalVisible(false)}
onClick={handleClose}
data-testid="cancel-create-file-button"
>
Cancel

View File

@@ -175,7 +175,7 @@ export interface DefaultFile {
export const DEFAULT_FILE: DefaultFile = {
name: 'New File.md',
path: 'New File.md',
content: '# Welcome to NovaMD\n\nStart editing here!',
content: '# Welcome to Lemma\n\nStart editing here!',
};
export interface FileNode {

View File

@@ -1,5 +1,17 @@
import { API_BASE_URL } from '@/types/api';
import { IMAGE_EXTENSIONS } from '@/types/models';
import { IMAGE_EXTENSIONS, type FileNode } from '@/types/models';
/**
* Represents a flattened file for searching and autocompletion
*/
export interface FlatFile {
name: string; // "meeting-notes.md"
path: string; // "work/2024/meeting-notes.md"
displayPath: string; // "work/2024/meeting-notes"
nameWithoutExt: string; // "meeting-notes"
parentFolder: string; // "work/2024"
isImage: boolean;
}
/**
* Checks if the given file path has an image extension.
@@ -15,3 +27,65 @@ export const getFileUrl = (workspaceName: string, filePath: string) => {
workspaceName
)}/files/content?file_path=${encodeURIComponent(filePath)}`;
};
/**
* Recursively flattens FileNode tree into searchable array
* Precomputes display strings and metadata for performance
*
* @param nodes - Array of FileNode from the file tree
* @param showHiddenFiles - Whether to include hidden files (files/folders starting with .)
* @returns Array of FlatFile objects ready for searching
*/
export function flattenFileTree(nodes: FileNode[], showHiddenFiles = false): FlatFile[] {
const result: FlatFile[] = [];
function traverse(node: FileNode) {
// Skip hidden files and folders if showHiddenFiles is false
// Hidden files/folders are those that start with a dot (.)
if (!showHiddenFiles && node.name.startsWith('.')) {
return;
}
// Only process files, not folders (folders have children)
if (!node.children) {
const name = node.name;
const path = node.path;
const isImage = isImageFile(path);
// Remove extension for display (except for images)
let nameWithoutExt = name;
let displayPath = path;
if (name.endsWith('.md')) {
nameWithoutExt = name.slice(0, -3);
displayPath = path.slice(0, -3);
}
// Get parent folder path
const lastSlashIndex = path.lastIndexOf('/');
const parentFolder = lastSlashIndex > 0 ? path.slice(0, lastSlashIndex) : '';
result.push({
name,
path,
displayPath,
nameWithoutExt,
parentFolder,
isImage,
});
}
// Recursively process children
if (node.children) {
for (const child of node.children) {
traverse(child);
}
}
}
for (const node of nodes) {
traverse(node);
}
return result;
}

View File

@@ -0,0 +1,44 @@
import type { FileNode } from '@/types/models';
/**
* Recursively filter tree to only include folders
* @param nodes - Array of FileNode objects
* @returns New tree structure with only folder nodes
*/
export const filterToFolders = (nodes: FileNode[]): FileNode[] => {
return nodes
.filter((node) => node.children !== undefined)
.map((node) => {
const filtered: FileNode = {
id: node.id,
name: node.name,
path: node.path,
};
if (node.children) {
filtered.children = filterToFolders(node.children);
}
return filtered;
});
};
/**
* Find a specific folder node by its path
* @param nodes - Array of FileNode objects
* @param path - Path to search for
* @returns The found FileNode or null
*/
export const findFolderByPath = (
nodes: FileNode[],
path: string
): FileNode | null => {
for (const node of nodes) {
if (node.path === path && node.children !== undefined) {
return node;
}
if (node.children) {
const found = findFolderByPath(node.children, path);
if (found) return found;
}
}
return null;
};

129
app/src/utils/fuzzyMatch.ts Normal file
View File

@@ -0,0 +1,129 @@
/**
* Result of a fuzzy match operation
*/
export interface MatchResult {
matched: boolean;
score: number; // Higher is better
matchedIndices: number[]; // For highlighting
}
/**
* Scoring weights for match quality
*/
const SCORING = {
consecutiveMatch: 15,
wordBoundaryMatch: 10,
camelCaseMatch: 10,
firstCharMatch: 15,
gapPenalty: -1,
} as const;
/**
* Performs fuzzy matching between query and target string
*
* Algorithm:
* - Sequential character matching (order matters)
* - Bonus for consecutive matches
* - Bonus for word boundary matches
* - Bonus for camelCase matches
* - Case-insensitive by default
*
* Example:
* query: "mtno"
* target: "meeting-notes"
* → matches: [0, 4, 8, 9], score: 85
*
* @param query - The search string
* @param target - The string to search in
* @returns MatchResult with matched status, score, and matched indices
*/
export function fuzzyMatch(query: string, target: string): MatchResult {
if (!query) {
return { matched: true, score: 0, matchedIndices: [] };
}
const queryLower = query.toLowerCase();
const targetLower = target.toLowerCase();
const matchedIndices: number[] = [];
let score = 0;
let queryIndex = 0;
let previousMatchIndex = -1;
// Try to match all query characters in order
for (let targetIndex = 0; targetIndex < targetLower.length; targetIndex++) {
if (queryIndex >= queryLower.length) {
break;
}
if (queryLower[queryIndex] === targetLower[targetIndex]) {
matchedIndices.push(targetIndex);
// Bonus for first character match
if (targetIndex === 0) {
score += SCORING.firstCharMatch;
}
// Bonus for consecutive matches
if (previousMatchIndex === targetIndex - 1) {
score += SCORING.consecutiveMatch;
} else if (previousMatchIndex >= 0) {
// Penalty for gaps
const gap = targetIndex - previousMatchIndex - 1;
score += gap * SCORING.gapPenalty;
}
// Bonus for word boundary matches
if (isWordBoundary(target, targetIndex)) {
score += SCORING.wordBoundaryMatch;
}
// Bonus for camelCase matches
if (isCamelCaseMatch(target, targetIndex)) {
score += SCORING.camelCaseMatch;
}
previousMatchIndex = targetIndex;
queryIndex++;
}
}
// All query characters must be matched
const matched = queryIndex === queryLower.length;
if (!matched) {
return { matched: false, score: 0, matchedIndices: [] };
}
// Boost score for matches with higher character coverage
const coverage = matchedIndices.length / target.length;
score += coverage * 50;
return { matched, score, matchedIndices };
}
/**
* Checks if a character at the given index is at a word boundary
* Word boundaries are: start of string, after space, after dash, after slash
*/
function isWordBoundary(str: string, index: number): boolean {
if (index === 0) return true;
const prevChar = str[index - 1];
return prevChar === ' ' || prevChar === '-' || prevChar === '/' || prevChar === '_';
}
/**
* Checks if a character at the given index is a camelCase boundary
* (lowercase followed by uppercase)
*/
function isCamelCaseMatch(str: string, index: number): boolean {
if (index === 0 || index >= str.length) return false;
const currentChar = str[index];
const prevChar = str[index - 1];
if (!currentChar || !prevChar) return false;
return (
currentChar === currentChar.toUpperCase() &&
currentChar !== currentChar.toLowerCase() &&
prevChar === prevChar.toLowerCase()
);
}

View File

@@ -240,17 +240,13 @@ export function remarkWikiLinks(workspaceName: string) {
continue;
}
const lookupFileName: string = match.isImage
? match.fileName
: addMarkdownExtension(match.fileName);
// If the filename contains a path separator, treat it as a full path
// This handles wikilinks with paths like [[folder/subfolder/file]]
let filePath: string;
if (match.fileName.includes('/')) {
// It's already a full path - use it directly
filePath = match.isImage ? match.fileName : addMarkdownExtension(match.fileName);
const paths: string[] = await lookupFileByName(
workspaceName,
lookupFileName
);
if (paths && paths.length > 0 && paths[0]) {
const filePath: string = paths[0];
if (match.isImage) {
newNodes.push(
createImageNode(workspaceName, filePath, match.displayText)
@@ -266,9 +262,37 @@ export function remarkWikiLinks(workspaceName: string) {
);
}
} else {
newNodes.push(
createNotFoundLink(match.fileName, match.displayText, baseUrl)
// It's just a filename - look it up to find the full path
const lookupFileName: string = match.isImage
? match.fileName
: addMarkdownExtension(match.fileName);
const paths: string[] = await lookupFileByName(
workspaceName,
lookupFileName
);
if (paths && paths.length > 0 && paths[0]) {
filePath = paths[0];
if (match.isImage) {
newNodes.push(
createImageNode(workspaceName, filePath, match.displayText)
);
} else {
newNodes.push(
createFileLink(
filePath,
match.displayText,
match.heading,
baseUrl
)
);
}
} else {
newNodes.push(
createNotFoundLink(match.fileName, match.displayText, baseUrl)
);
}
}
} catch (error) {
console.debug('File lookup failed:', match.fileName, error);

View File

@@ -0,0 +1,239 @@
import type {
CompletionContext,
CompletionResult,
Completion,
} from '@codemirror/autocomplete';
import type { FlatFile } from './fileHelpers';
import { fuzzyMatch } from './fuzzyMatch';
/**
* Wiki link context detection result
*/
interface WikiLinkContext {
isWikiLink: boolean;
isImage: boolean; // true if ![[
query: string; // partial text after [[
from: number; // cursor position to replace from
to: number; // cursor position to replace to
}
/**
* Creates CodeMirror autocompletion source for wiki links
*
* @param files - Flattened file list from workspace
* @returns CompletionSource function
*/
export function createWikiLinkCompletions(
files: FlatFile[]
): (context: CompletionContext) => CompletionResult | null {
return (context: CompletionContext): CompletionResult | null => {
const wikiContext = detectWikiLinkContext(context);
if (!wikiContext.isWikiLink) {
return null;
}
// Filter and rank files based on query
const rankedFiles = filterAndRankFiles(
wikiContext.query,
files,
wikiContext.isImage,
50
);
if (rankedFiles.length === 0) {
return null;
}
// Convert to completion options
const options = rankedFiles.map((file) => formatCompletion(file));
return {
from: wikiContext.from,
to: wikiContext.to,
options,
// Don't set filter or validFor - let CodeMirror re-trigger our completion
// source on every keystroke so we can re-filter with fuzzy matching
};
};
}
/**
* Detects if cursor is inside a wiki link and extracts context
*
* Detection logic:
* 1. Search backwards from cursor for [[ or ![[
* 2. Ensure no closing ]] between opener and cursor
* 3. Extract partial query (text after [[ and before cursor)
* 4. Determine if image link (![[) or regular ([[)
*
* Examples:
* "[[meeti|ng" → { isWikiLink: true, query: "meeti", ... }
* "![[img|" → { isWikiLink: true, isImage: true, query: "img", ... }
* "regular text|" → { isWikiLink: false }
*/
function detectWikiLinkContext(context: CompletionContext): WikiLinkContext {
const { state, pos } = context;
const line = state.doc.lineAt(pos);
const textBefore = state.sliceDoc(line.from, pos);
// Look for [[ or ![[
const imageWikiLinkMatch = textBefore.lastIndexOf('![[');
const regularWikiLinkMatch = textBefore.lastIndexOf('[[');
// Determine which one is closer to cursor
let isImage = false;
let openerIndex = -1;
if (imageWikiLinkMatch > regularWikiLinkMatch) {
isImage = true;
openerIndex = imageWikiLinkMatch;
} else if (regularWikiLinkMatch >= 0) {
openerIndex = regularWikiLinkMatch;
}
// If no opener found, not in a wiki link
if (openerIndex < 0) {
return {
isWikiLink: false,
isImage: false,
query: '',
from: pos,
to: pos,
};
}
// Calculate the absolute position of the opener in the document
const openerPos = line.from + openerIndex;
const openerLength = isImage ? 3 : 2; // ![[ or [[
const queryStartPos = openerPos + openerLength;
// Check if there's a closing ]] between opener and cursor
const textAfterOpener = textBefore.slice(openerIndex);
const closingIndex = textAfterOpener.indexOf(']]');
if (closingIndex >= 0 && closingIndex < textAfterOpener.length - 2) {
// Found ]] before cursor, so we're not inside a wiki link
return {
isWikiLink: false,
isImage: false,
query: '',
from: pos,
to: pos,
};
}
// Extract the query (text between [[ and cursor)
const query = state.sliceDoc(queryStartPos, pos);
return {
isWikiLink: true,
isImage,
query,
from: queryStartPos,
to: pos,
};
}
/**
* Filters files and ranks by relevance
*
* Ranking priority:
* 1. File type match (images for ![[, markdown for [[)
* 2. Fuzzy match score
* 3. Exact filename match > path component match
* 4. Shorter paths (prefer root over deeply nested)
* 5. Alphabetical for ties
*
* @param query - User's partial input
* @param files - All available files
* @param isImage - Whether to filter for images
* @param maxResults - Limit returned results (default: 50)
*/
function filterAndRankFiles(
query: string,
files: FlatFile[],
isImage: boolean,
maxResults = 50
): FlatFile[] {
// If query is empty, show all matching file types
if (!query) {
const filtered = files.filter((f) => f.isImage === isImage);
return filtered.slice(0, maxResults);
}
interface ScoredFile {
file: FlatFile;
score: number;
nameScore: number;
pathScore: number;
}
const scored: ScoredFile[] = [];
for (const file of files) {
// Filter by file type
if (file.isImage !== isImage) {
continue;
}
// Try matching against different fields
const nameMatch = fuzzyMatch(query, file.nameWithoutExt);
const pathMatch = fuzzyMatch(query, file.displayPath);
// Use the best match
if (nameMatch.matched || pathMatch.matched) {
// Prefer name matches over path matches
const nameScore = nameMatch.matched ? nameMatch.score : 0;
const pathScore = pathMatch.matched ? pathMatch.score : 0;
// Name matches get higher priority
const totalScore = nameScore * 2 + pathScore;
// Penalize deeply nested files slightly
const depth = file.path.split('/').length;
const depthPenalty = depth * 0.5;
scored.push({
file,
score: totalScore - depthPenalty,
nameScore,
pathScore,
});
}
}
// Sort by score (descending), then alphabetically
scored.sort((a, b) => {
if (b.score !== a.score) {
return b.score - a.score;
}
return a.file.displayPath.localeCompare(b.file.displayPath);
});
// Return top results
return scored.slice(0, maxResults).map((s) => s.file);
}
/**
* Converts FlatFile to CodeMirror Completion object
*
* Format rules:
* - Markdown files: show path without .md extension
* - Images: show full path with extension
* - Display includes path relative to workspace root
* - Apply text: full path (no extension for .md)
*
* Example outputs:
* work/2024/meeting-notes (for .md)
* assets/screenshot.png (for image)
*/
function formatCompletion(file: FlatFile): Completion {
return {
label: file.displayPath,
apply: file.displayPath,
type: file.isImage ? 'image' : 'file',
detail: file.parentFolder || '/',
boost: 0,
};
}

View File

@@ -1,63 +1,63 @@
module lemma
go 1.23.1
go 1.24.0
require (
github.com/go-chi/chi/v5 v5.2.2
github.com/go-chi/cors v1.2.1
github.com/go-chi/httprate v0.14.1
github.com/go-git/go-git/v5 v5.13.1
github.com/go-playground/validator/v10 v10.22.1
github.com/golang-jwt/jwt/v5 v5.2.2
github.com/golang-migrate/migrate/v4 v4.18.2
github.com/go-chi/chi/v5 v5.2.3
github.com/go-chi/cors v1.2.2
github.com/go-chi/httprate v0.15.0
github.com/go-git/go-git/v5 v5.16.4
github.com/go-playground/validator/v10 v10.29.0
github.com/golang-jwt/jwt/v5 v5.3.0
github.com/golang-migrate/migrate/v4 v4.19.1
github.com/google/uuid v1.6.0
github.com/lib/pq v1.10.9
github.com/mattn/go-sqlite3 v1.14.23
github.com/stretchr/testify v1.10.0
github.com/mattn/go-sqlite3 v1.14.32
github.com/stretchr/testify v1.11.1
github.com/swaggo/http-swagger v1.3.4
github.com/swaggo/swag v1.16.4
github.com/swaggo/swag v1.16.6
github.com/unrolled/secure v1.17.0
golang.org/x/crypto v0.36.0
golang.org/x/crypto v0.46.0
)
require (
dario.cat/mergo v1.0.0 // indirect
github.com/KyleBanks/depth v1.2.1 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/ProtonMail/go-crypto v1.1.3 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/ProtonMail/go-crypto v1.1.6 // indirect
github.com/cloudflare/circl v1.6.1 // indirect
github.com/cyphar/filepath-securejoin v0.3.6 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gabriel-vasile/mimetype v1.4.11 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.6.1 // indirect
github.com/go-git/go-billy/v5 v5.6.2 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/jsonreference v0.20.0 // indirect
github.com/go-openapi/spec v0.20.6 // indirect
github.com/go-openapi/swag v0.19.15 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mailru/easyjson v0.7.6 // indirect
github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/pjbgf/sha1cd v0.3.2 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
github.com/skeema/knownhosts v1.3.0 // indirect
github.com/skeema/knownhosts v1.3.1 // indirect
github.com/swaggo/files v0.0.0-20220610200504-28940afbdbfe // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
go.uber.org/atomic v1.7.0 // indirect
golang.org/x/net v0.38.0 // indirect
golang.org/x/sys v0.31.0 // indirect
golang.org/x/text v0.23.0 // indirect
golang.org/x/tools v0.24.0 // indirect
github.com/zeebo/xxh3 v1.0.2 // indirect
golang.org/x/mod v0.30.0 // indirect
golang.org/x/net v0.47.0 // indirect
golang.org/x/sync v0.19.0 // indirect
golang.org/x/sys v0.39.0 // indirect
golang.org/x/text v0.32.0 // indirect
golang.org/x/tools v0.39.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect

View File

@@ -7,58 +7,61 @@ github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6Xge
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/ProtonMail/go-crypto v1.1.3 h1:nRBOetoydLeUb4nHajyO2bKqMLfWQ/ZPwkXqXxPxCFk=
github.com/ProtonMail/go-crypto v1.1.3/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
github.com/ProtonMail/go-crypto v1.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNxpLfdw=
github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM=
github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dhui/dktest v0.4.4 h1:+I4s6JRE1yGuqflzwqG+aIaMdgXIorCf5P98JnaAWa8=
github.com/dhui/dktest v0.4.4/go.mod h1:4+22R4lgsdAXrDyaH4Nqx2JEz2hLp49MqQmm9HLCQhM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dhui/dktest v0.4.6 h1:+DPKyScKSEp3VLtbMDHcUq6V5Lm5zfZZVb0Sk7Ahom4=
github.com/dhui/dktest v0.4.6/go.mod h1:JHTSYDtKkvFNFHJKqCzVzqXecyv+tKt8EzceOmQOgbU=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/docker/docker v27.2.0+incompatible h1:Rk9nIVdfH3+Vz4cyI/uhbINhEZ/oLmc+CBXmH6fbNk4=
github.com/docker/docker v27.2.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v28.3.3+incompatible h1:Dypm25kh4rmk49v1eiVbsAtpAsYURjYkaKubwuBdxEI=
github.com/docker/docker v28.3.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/elazarl/goproxy v1.2.3 h1:xwIyKHbaP5yfT6O9KIeYJR5549MXRQkoQMRXGztz8YQ=
github.com/elazarl/goproxy v1.2.3/go.mod h1:YfEbZtqP4AetfO6d40vWchF3znWX7C7Vd6ZMfdL8z64=
github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o=
github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/gabriel-vasile/mimetype v1.4.11 h1:AQvxbp830wPhHTqc1u7nzoLT+ZFxGY7emj5DR5DYFik=
github.com/gabriel-vasile/mimetype v1.4.11/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=
github.com/go-chi/chi/v5 v5.2.2 h1:CMwsvRVTbXVytCk1Wd72Zy1LAsAh9GxMmSNWLHCG618=
github.com/go-chi/chi/v5 v5.2.2/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
github.com/go-chi/httprate v0.14.1 h1:EKZHYEZ58Cg6hWcYzoZILsv7ppb46Wt4uQ738IRtpZs=
github.com/go-chi/httprate v0.14.1/go.mod h1:TUepLXaz/pCjmCtf/obgOQJ2Sz6rC8fSf5cAt5cnTt0=
github.com/go-chi/chi/v5 v5.2.3 h1:WQIt9uxdsAbgIYgid+BpYc+liqQZGMHRaUwp0JUcvdE=
github.com/go-chi/chi/v5 v5.2.3/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
github.com/go-chi/cors v1.2.2 h1:Jmey33TE+b+rB7fT8MUy1u0I4L+NARQlK6LhzKPSyQE=
github.com/go-chi/cors v1.2.2/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
github.com/go-chi/httprate v0.15.0 h1:j54xcWV9KGmPf/X4H32/aTH+wBlrvxL7P+SdnRqxh5g=
github.com/go-chi/httprate v0.15.0/go.mod h1:rzGHhVrsBn3IMLYDOZQsSU4fJNWcjui4fWKJcCId1R4=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
github.com/go-git/go-billy/v5 v5.6.1 h1:u+dcrgaguSSkbjzHwelEjc0Yj300NUevrrPphk/SoRA=
github.com/go-git/go-billy/v5 v5.6.1/go.mod h1:0AsLr1z2+Uksi4NlElmMblP5rPcDZNRCD8ujZCRR2BE=
github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM=
github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
github.com/go-git/go-git/v5 v5.13.1 h1:DAQ9APonnlvSWpvolXWIuV6Q6zXy2wHbN4cVlNR5Q+M=
github.com/go-git/go-git/v5 v5.13.1/go.mod h1:qryJB4cSBoq3FRoBRf5A77joojuBcmPJ0qu3XXXVixc=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-git/go-git/v5 v5.16.4 h1:7ajIEZHZJULcyJebDLo99bGgS0jRrOxzZG4uCk2Yb2Y=
github.com/go-git/go-git/v5 v5.16.4/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
@@ -77,31 +80,28 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA=
github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/go-playground/validator/v10 v10.29.0 h1:lQlF5VNJWNlRbRZNeOIkWElR+1LL/OuHcc0Kp14w1xk=
github.com/go-playground/validator/v10 v10.29.0/go.mod h1:D6QxqeMlgIPuT02L66f2ccrZ7AGgHkzKmmTMZhk/Kc4=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang-migrate/migrate/v4 v4.18.2 h1:2VSCMz7x7mjyTXx3m2zPokOY82LTRgxK1yQYKo6wWQ8=
github.com/golang-migrate/migrate/v4 v4.18.2/go.mod h1:2CM6tJvn2kqPXwnXO/d3rAQYiyoIm180VsO8PRX6Rpk=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/golang-migrate/migrate/v4 v4.19.1 h1:OCyb44lFuQfYXYLx1SCxPZQGU7mcaZ7gH9yH4jSFbBA=
github.com/golang-migrate/migrate/v4 v4.19.1/go.mod h1:CTcgfjxhaUtsLipnLoQRWCrjYXycRz/g5+RWDuYgPrE=
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
@@ -117,8 +117,8 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-sqlite3 v1.14.23 h1:gbShiuAP1W5j9UOksQ06aiiqPMxYecovVGwmTxWtuw0=
github.com/mattn/go-sqlite3 v1.14.23/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs=
github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
@@ -132,76 +132,81 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4=
github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY=
github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M=
github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8=
github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/swaggo/files v0.0.0-20220610200504-28940afbdbfe h1:K8pHPVoTgxFJt1lXuIzzOX7zZhZFldJQK/CgKx9BFIc=
github.com/swaggo/files v0.0.0-20220610200504-28940afbdbfe/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w=
github.com/swaggo/http-swagger v1.3.4 h1:q7t/XLx0n15H1Q9/tk3Y9L4n210XzJF5WtnDX64a5ww=
github.com/swaggo/http-swagger v1.3.4/go.mod h1:9dAh0unqMBAlbp1uE2Uc2mQTxNMU/ha4UbucIg1MFkQ=
github.com/swaggo/swag v1.16.4 h1:clWJtd9LStiG3VeijiCfOVODP6VpHtKdQy9ELFG3s1A=
github.com/swaggo/swag v1.16.4/go.mod h1:VBsHJRsDvfYvqoiMKnsdwhNV9LEMHgEDZcyVYX0sxPg=
github.com/swaggo/swag v1.16.6 h1:qBNcx53ZaX+M5dxVyTrgQ0PJ/ACK+NzhwcbieTt+9yI=
github.com/swaggo/swag v1.16.6/go.mod h1:ngP2etMK5a0P3QBizic5MEwpRmluJZPHjXcMoj4Xesg=
github.com/unrolled/secure v1.17.0 h1:Io7ifFgo99Bnh0J7+Q+qcMzWM6kaDPCA5FroFZEdbWU=
github.com/unrolled/secure v1.17.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8=
go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw=
go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8=
go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc=
go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8=
go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4=
go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ=
github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0=
github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk=
golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=
golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ=
golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=