@structured-world/gitlab-mcp 6.62.1 → 7.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -1
- package/README.md.in +21 -0
- package/dist/generated/prisma/client.js.map +1 -1
- package/dist/generated/prisma/internal/class.js +2 -2
- package/dist/generated/prisma/internal/class.js.map +1 -1
- package/dist/generated/prisma/internal/prismaNamespace.js +2 -2
- package/dist/generated/prisma/models/AuthCodeFlowState.d.ts +1 -2
- package/dist/generated/prisma/models/AuthorizationCode.d.ts +1 -2
- package/dist/generated/prisma/models/DeviceFlowState.d.ts +1 -2
- package/dist/generated/prisma/models/McpSessionMapping.d.ts +1 -2
- package/dist/generated/prisma/models/OAuthSession.d.ts +1 -2
- package/dist/src/cli/docker/container-runtime.d.ts +1 -1
- package/dist/src/cli/docker/container-runtime.js +14 -14
- package/dist/src/cli/docker/docker-command.d.ts +1 -1
- package/dist/src/cli/docker/docker-command.js +113 -113
- package/dist/src/cli/docker/docker-command.js.map +1 -1
- package/dist/src/cli/docker/docker-utils.d.ts +3 -3
- package/dist/src/cli/docker/docker-utils.js +74 -74
- package/dist/src/cli/docker/docker-utils.js.map +1 -1
- package/dist/src/cli/docker/index.d.ts +4 -4
- package/dist/src/cli/docker/types.d.ts +3 -3
- package/dist/src/cli/docker/types.js +5 -5
- package/dist/src/cli/init/browser.js +2 -2
- package/dist/src/cli/init/config-generator.d.ts +2 -2
- package/dist/src/cli/init/config-generator.js +22 -22
- package/dist/src/cli/init/connection.d.ts +1 -1
- package/dist/src/cli/init/connection.js +27 -27
- package/dist/src/cli/init/connection.js.map +1 -1
- package/dist/src/cli/init/index.d.ts +4 -4
- package/dist/src/cli/init/types.d.ts +3 -3
- package/dist/src/cli/init/types.js +36 -36
- package/dist/src/cli/init/wizard.js +80 -80
- package/dist/src/cli/init/wizard.js.map +1 -1
- package/dist/src/cli/inject-tool-refs.js +47 -47
- package/dist/src/cli/inject-tool-refs.js.map +1 -1
- package/dist/src/cli/install/backup.d.ts +1 -1
- package/dist/src/cli/install/backup.js +3 -3
- package/dist/src/cli/install/detector.d.ts +2 -2
- package/dist/src/cli/install/detector.js +18 -18
- package/dist/src/cli/install/detector.js.map +1 -1
- package/dist/src/cli/install/index.d.ts +5 -5
- package/dist/src/cli/install/install-command.d.ts +2 -2
- package/dist/src/cli/install/install-command.js +68 -68
- package/dist/src/cli/install/install-command.js.map +1 -1
- package/dist/src/cli/install/installers.d.ts +2 -2
- package/dist/src/cli/install/installers.js +55 -55
- package/dist/src/cli/install/installers.js.map +1 -1
- package/dist/src/cli/install/types.d.ts +4 -4
- package/dist/src/cli/install/types.js +48 -48
- package/dist/src/cli/instances/index.d.ts +2 -2
- package/dist/src/cli/instances/instances-command.d.ts +1 -1
- package/dist/src/cli/instances/instances-command.js +70 -66
- package/dist/src/cli/instances/instances-command.js.map +1 -1
- package/dist/src/cli/list-tools.js +396 -396
- package/dist/src/cli/list-tools.js.map +1 -1
- package/dist/src/cli/setup/discovery.d.ts +1 -1
- package/dist/src/cli/setup/discovery.js +10 -10
- package/dist/src/cli/setup/discovery.js.map +1 -1
- package/dist/src/cli/setup/flows/configure-existing.d.ts +1 -1
- package/dist/src/cli/setup/flows/configure-existing.js +57 -57
- package/dist/src/cli/setup/flows/configure-existing.js.map +1 -1
- package/dist/src/cli/setup/flows/local-setup.d.ts +1 -1
- package/dist/src/cli/setup/flows/local-setup.js +51 -51
- package/dist/src/cli/setup/flows/local-setup.js.map +1 -1
- package/dist/src/cli/setup/flows/server-setup.d.ts +1 -1
- package/dist/src/cli/setup/flows/server-setup.js +50 -50
- package/dist/src/cli/setup/flows/server-setup.js.map +1 -1
- package/dist/src/cli/setup/flows/tool-selection.d.ts +1 -1
- package/dist/src/cli/setup/flows/tool-selection.js +94 -94
- package/dist/src/cli/setup/flows/tool-selection.js.map +1 -1
- package/dist/src/cli/setup/index.d.ts +4 -4
- package/dist/src/cli/setup/presets.d.ts +1 -1
- package/dist/src/cli/setup/presets.js +157 -157
- package/dist/src/cli/setup/presets.js.map +1 -1
- package/dist/src/cli/setup/types.d.ts +7 -7
- package/dist/src/cli/setup/wizard.d.ts +1 -1
- package/dist/src/cli/setup/wizard.js +25 -25
- package/dist/src/cli/utils/index.d.ts +1 -1
- package/dist/src/cli/utils/path-utils.js +3 -3
- package/dist/src/cli-utils.d.ts +2 -2
- package/dist/src/cli-utils.js +46 -46
- package/dist/src/config/index.d.ts +4 -4
- package/dist/src/config/instances-loader.d.ts +3 -3
- package/dist/src/config/instances-loader.js +53 -53
- package/dist/src/config/instances-loader.js.map +1 -1
- package/dist/src/config/instances-schema.d.ts +1 -1
- package/dist/src/config/instances-schema.js +33 -33
- package/dist/src/config/instances-schema.js.map +1 -1
- package/dist/src/config.d.ts +11 -4
- package/dist/src/config.js +112 -111
- package/dist/src/config.js.map +1 -1
- package/dist/src/dashboard/handler.d.ts +2 -2
- package/dist/src/dashboard/handler.js +7 -7
- package/dist/src/dashboard/html-template.d.ts +1 -1
- package/dist/src/dashboard/html-template.js +44 -44
- package/dist/src/dashboard/html-template.js.map +1 -1
- package/dist/src/dashboard/index.d.ts +4 -4
- package/dist/src/dashboard/metrics.d.ts +3 -3
- package/dist/src/dashboard/metrics.js +42 -42
- package/dist/src/discovery/auto.d.ts +3 -3
- package/dist/src/discovery/auto.js +28 -28
- package/dist/src/discovery/git-remote.d.ts +2 -2
- package/dist/src/discovery/git-remote.js +18 -18
- package/dist/src/discovery/index.d.ts +3 -3
- package/dist/src/discovery/profile-matcher.d.ts +2 -2
- package/dist/src/discovery/profile-matcher.js +8 -8
- package/dist/src/discovery/profile-matcher.js.map +1 -1
- package/dist/src/entities/context/context-manager.d.ts +3 -3
- package/dist/src/entities/context/context-manager.js +34 -34
- package/dist/src/entities/context/context-manager.js.map +1 -1
- package/dist/src/entities/context/handlers.d.ts +2 -2
- package/dist/src/entities/context/handlers.js +8 -8
- package/dist/src/entities/context/index.d.ts +8 -8
- package/dist/src/entities/context/index.js +1 -1
- package/dist/src/entities/context/registry.d.ts +1 -1
- package/dist/src/entities/context/registry.js +4 -4
- package/dist/src/entities/context/schema.d.ts +1 -1
- package/dist/src/entities/context/schema.js +19 -19
- package/dist/src/entities/context/types.d.ts +9 -9
- package/dist/src/entities/context/whoami.d.ts +1 -1
- package/dist/src/entities/context/whoami.js +31 -31
- package/dist/src/entities/context/whoami.js.map +1 -1
- package/dist/src/entities/core/index.d.ts +5 -5
- package/dist/src/entities/core/index.js +1 -1
- package/dist/src/entities/core/registry.d.ts +1 -1
- package/dist/src/entities/core/registry.js +194 -194
- package/dist/src/entities/core/registry.js.map +1 -1
- package/dist/src/entities/core/schema-readonly.d.ts +1 -1
- package/dist/src/entities/core/schema-readonly.js +117 -117
- package/dist/src/entities/core/schema.d.ts +1 -1
- package/dist/src/entities/core/schema.js +67 -67
- package/dist/src/entities/files/index.d.ts +5 -5
- package/dist/src/entities/files/index.js +1 -1
- package/dist/src/entities/files/registry.d.ts +1 -1
- package/dist/src/entities/files/registry.js +45 -45
- package/dist/src/entities/files/registry.js.map +1 -1
- package/dist/src/entities/files/schema-readonly.d.ts +1 -1
- package/dist/src/entities/files/schema-readonly.js +13 -13
- package/dist/src/entities/files/schema.d.ts +1 -1
- package/dist/src/entities/files/schema.js +29 -29
- package/dist/src/entities/index.d.ts +17 -17
- package/dist/src/entities/integrations/index.d.ts +4 -4
- package/dist/src/entities/integrations/registry.d.ts +1 -1
- package/dist/src/entities/integrations/registry.js +17 -17
- package/dist/src/entities/integrations/registry.js.map +1 -1
- package/dist/src/entities/integrations/schema-readonly.d.ts +1 -1
- package/dist/src/entities/integrations/schema-readonly.js +5 -5
- package/dist/src/entities/integrations/schema.d.ts +1 -1
- package/dist/src/entities/integrations/schema.js +69 -69
- package/dist/src/entities/iterations/index.d.ts +2 -2
- package/dist/src/entities/iterations/registry.d.ts +1 -1
- package/dist/src/entities/iterations/registry.js +13 -13
- package/dist/src/entities/iterations/registry.js.map +1 -1
- package/dist/src/entities/iterations/schema-readonly.d.ts +1 -1
- package/dist/src/entities/iterations/schema-readonly.js +9 -9
- package/dist/src/entities/labels/index.d.ts +5 -5
- package/dist/src/entities/labels/index.js +1 -1
- package/dist/src/entities/labels/registry.d.ts +1 -1
- package/dist/src/entities/labels/registry.js +19 -19
- package/dist/src/entities/labels/registry.js.map +1 -1
- package/dist/src/entities/labels/schema-readonly.d.ts +1 -1
- package/dist/src/entities/labels/schema-readonly.js +8 -8
- package/dist/src/entities/labels/schema.d.ts +1 -1
- package/dist/src/entities/labels/schema.js +11 -11
- package/dist/src/entities/members/index.d.ts +3 -3
- package/dist/src/entities/members/registry.d.ts +1 -1
- package/dist/src/entities/members/registry.js +26 -26
- package/dist/src/entities/members/registry.js.map +1 -1
- package/dist/src/entities/members/schema-readonly.d.ts +1 -1
- package/dist/src/entities/members/schema-readonly.js +32 -32
- package/dist/src/entities/members/schema-readonly.js.map +1 -1
- package/dist/src/entities/members/schema.d.ts +1 -1
- package/dist/src/entities/members/schema.js +28 -28
- package/dist/src/entities/milestones/index.d.ts +5 -5
- package/dist/src/entities/milestones/index.js +1 -1
- package/dist/src/entities/milestones/registry.d.ts +1 -1
- package/dist/src/entities/milestones/registry.js +25 -25
- package/dist/src/entities/milestones/registry.js.map +1 -1
- package/dist/src/entities/milestones/schema-readonly.d.ts +2 -2
- package/dist/src/entities/milestones/schema-readonly.js +15 -15
- package/dist/src/entities/milestones/schema.d.ts +1 -1
- package/dist/src/entities/milestones/schema.js +16 -16
- package/dist/src/entities/milestones/schema.js.map +1 -1
- package/dist/src/entities/mrs/index.d.ts +5 -5
- package/dist/src/entities/mrs/index.js +1 -1
- package/dist/src/entities/mrs/registry.d.ts +1 -1
- package/dist/src/entities/mrs/registry.js +102 -102
- package/dist/src/entities/mrs/registry.js.map +1 -1
- package/dist/src/entities/mrs/schema-readonly.d.ts +1 -1
- package/dist/src/entities/mrs/schema-readonly.js +126 -126
- package/dist/src/entities/mrs/schema-readonly.js.map +1 -1
- package/dist/src/entities/mrs/schema.d.ts +1 -1
- package/dist/src/entities/mrs/schema.js +111 -111
- package/dist/src/entities/mrs/schema.js.map +1 -1
- package/dist/src/entities/pipelines/index.d.ts +5 -5
- package/dist/src/entities/pipelines/index.js +1 -1
- package/dist/src/entities/pipelines/registry.d.ts +1 -1
- package/dist/src/entities/pipelines/registry.js +45 -45
- package/dist/src/entities/pipelines/registry.js.map +1 -1
- package/dist/src/entities/pipelines/schema-readonly.d.ts +2 -2
- package/dist/src/entities/pipelines/schema-readonly.js +73 -73
- package/dist/src/entities/pipelines/schema.d.ts +1 -1
- package/dist/src/entities/pipelines/schema.js +21 -21
- package/dist/src/entities/refs/index.d.ts +3 -3
- package/dist/src/entities/refs/registry.d.ts +1 -1
- package/dist/src/entities/refs/registry.js +31 -31
- package/dist/src/entities/refs/registry.js.map +1 -1
- package/dist/src/entities/refs/schema-readonly.d.ts +1 -1
- package/dist/src/entities/refs/schema-readonly.js +21 -21
- package/dist/src/entities/refs/schema.d.ts +1 -1
- package/dist/src/entities/refs/schema.js +56 -56
- package/dist/src/entities/releases/index.d.ts +3 -3
- package/dist/src/entities/releases/registry.d.ts +1 -1
- package/dist/src/entities/releases/registry.js +21 -21
- package/dist/src/entities/releases/registry.js.map +1 -1
- package/dist/src/entities/releases/schema-readonly.d.ts +1 -1
- package/dist/src/entities/releases/schema-readonly.js +13 -13
- package/dist/src/entities/releases/schema.d.ts +1 -1
- package/dist/src/entities/releases/schema.js +21 -21
- package/dist/src/entities/search/index.d.ts +2 -2
- package/dist/src/entities/search/registry.d.ts +1 -1
- package/dist/src/entities/search/registry.js +13 -13
- package/dist/src/entities/search/schema-readonly.d.ts +1 -1
- package/dist/src/entities/search/schema-readonly.js +23 -23
- package/dist/src/entities/shared.d.ts +1 -1
- package/dist/src/entities/shared.js +5 -5
- package/dist/src/entities/snippets/index.d.ts +5 -5
- package/dist/src/entities/snippets/index.js +1 -1
- package/dist/src/entities/snippets/registry.d.ts +1 -1
- package/dist/src/entities/snippets/registry.js +24 -24
- package/dist/src/entities/snippets/registry.js.map +1 -1
- package/dist/src/entities/snippets/schema-readonly.d.ts +1 -1
- package/dist/src/entities/snippets/schema-readonly.js +11 -11
- package/dist/src/entities/snippets/schema.d.ts +1 -1
- package/dist/src/entities/snippets/schema.js +27 -27
- package/dist/src/entities/snippets/schema.js.map +1 -1
- package/dist/src/entities/utils.d.ts +2 -2
- package/dist/src/entities/utils.js +8 -8
- package/dist/src/entities/utils.js.map +1 -1
- package/dist/src/entities/variables/index.d.ts +5 -5
- package/dist/src/entities/variables/index.js +1 -1
- package/dist/src/entities/variables/registry.d.ts +1 -1
- package/dist/src/entities/variables/registry.js +22 -22
- package/dist/src/entities/variables/registry.js.map +1 -1
- package/dist/src/entities/variables/schema-readonly.d.ts +1 -1
- package/dist/src/entities/variables/schema-readonly.js +6 -6
- package/dist/src/entities/variables/schema.d.ts +1 -1
- package/dist/src/entities/variables/schema.js +21 -21
- package/dist/src/entities/variables/schema.js.map +1 -1
- package/dist/src/entities/webhooks/index.d.ts +4 -4
- package/dist/src/entities/webhooks/registry.d.ts +1 -1
- package/dist/src/entities/webhooks/registry.js +29 -29
- package/dist/src/entities/webhooks/registry.js.map +1 -1
- package/dist/src/entities/webhooks/schema-readonly.d.ts +1 -1
- package/dist/src/entities/webhooks/schema-readonly.js +9 -9
- package/dist/src/entities/webhooks/schema.d.ts +1 -1
- package/dist/src/entities/webhooks/schema.js +59 -59
- package/dist/src/entities/wiki/index.d.ts +5 -5
- package/dist/src/entities/wiki/index.js +1 -1
- package/dist/src/entities/wiki/registry.d.ts +1 -1
- package/dist/src/entities/wiki/registry.js +19 -19
- package/dist/src/entities/wiki/registry.js.map +1 -1
- package/dist/src/entities/wiki/schema-readonly.d.ts +1 -1
- package/dist/src/entities/wiki/schema-readonly.js +6 -6
- package/dist/src/entities/wiki/schema.d.ts +1 -1
- package/dist/src/entities/wiki/schema.js +12 -12
- package/dist/src/entities/workitems/index.d.ts +5 -5
- package/dist/src/entities/workitems/index.js +1 -1
- package/dist/src/entities/workitems/registry.d.ts +1 -1
- package/dist/src/entities/workitems/registry.js +101 -101
- package/dist/src/entities/workitems/registry.js.map +1 -1
- package/dist/src/entities/workitems/schema-readonly.d.ts +1 -1
- package/dist/src/entities/workitems/schema-readonly.js +27 -27
- package/dist/src/entities/workitems/schema-readonly.js.map +1 -1
- package/dist/src/entities/workitems/schema.d.ts +1 -1
- package/dist/src/entities/workitems/schema.js +58 -58
- package/dist/src/graphql/DynamicWorkItemsQuery.d.ts +2 -2
- package/dist/src/graphql/DynamicWorkItemsQuery.js +47 -47
- package/dist/src/graphql/DynamicWorkItemsQuery.js.map +1 -1
- package/dist/src/graphql/client.d.ts +1 -1
- package/dist/src/graphql/client.js +4 -4
- package/dist/src/graphql/client.js.map +1 -1
- package/dist/src/graphql/index.d.ts +2 -2
- package/dist/src/graphql/workItems.d.ts +38 -38
- package/dist/src/graphql/workItems.js +30 -30
- package/dist/src/handlers.d.ts +2 -1
- package/dist/src/handlers.js +258 -86
- package/dist/src/handlers.js.map +1 -1
- package/dist/src/http-client.js +3 -3
- package/dist/src/logger.js +25 -25
- package/dist/src/logging/access-log.d.ts +2 -2
- package/dist/src/logging/access-log.js +25 -25
- package/dist/src/logging/connection-tracker.d.ts +1 -1
- package/dist/src/logging/connection-tracker.js +3 -3
- package/dist/src/logging/index.d.ts +5 -5
- package/dist/src/logging/request-tracker.d.ts +3 -3
- package/dist/src/logging/request-tracker.js +4 -4
- package/dist/src/logging/types.d.ts +3 -3
- package/dist/src/logging/types.js +1 -1
- package/dist/src/logging/types.js.map +1 -1
- package/dist/src/main.js +28 -28
- package/dist/src/middleware/index.d.ts +3 -2
- package/dist/src/middleware/index.js +3 -1
- package/dist/src/middleware/index.js.map +1 -1
- package/dist/src/middleware/oauth-auth.d.ts +1 -1
- package/dist/src/middleware/oauth-auth.js +17 -17
- package/dist/src/middleware/rate-limiter.d.ts +1 -1
- package/dist/src/middleware/rate-limiter.js +32 -32
- package/dist/src/middleware/response-write-timeout.d.ts +2 -0
- package/dist/src/middleware/response-write-timeout.js +62 -0
- package/dist/src/middleware/response-write-timeout.js.map +1 -0
- package/dist/src/oauth/config.d.ts +1 -1
- package/dist/src/oauth/config.js +18 -18
- package/dist/src/oauth/config.js.map +1 -1
- package/dist/src/oauth/endpoints/authorize.d.ts +1 -1
- package/dist/src/oauth/endpoints/authorize.js +32 -32
- package/dist/src/oauth/endpoints/callback.d.ts +1 -1
- package/dist/src/oauth/endpoints/callback.js +26 -26
- package/dist/src/oauth/endpoints/index.d.ts +5 -5
- package/dist/src/oauth/endpoints/metadata.d.ts +1 -1
- package/dist/src/oauth/endpoints/metadata.js +12 -12
- package/dist/src/oauth/endpoints/register.d.ts +1 -1
- package/dist/src/oauth/endpoints/register.js +9 -9
- package/dist/src/oauth/endpoints/token.d.ts +1 -1
- package/dist/src/oauth/endpoints/token.js +28 -28
- package/dist/src/oauth/gitlab-device-flow.d.ts +2 -2
- package/dist/src/oauth/gitlab-device-flow.js +73 -68
- package/dist/src/oauth/gitlab-device-flow.js.map +1 -1
- package/dist/src/oauth/index.d.ts +10 -10
- package/dist/src/oauth/session-store.d.ts +2 -2
- package/dist/src/oauth/session-store.js +40 -40
- package/dist/src/oauth/session-store.js.map +1 -1
- package/dist/src/oauth/storage/factory.d.ts +2 -2
- package/dist/src/oauth/storage/factory.js +16 -16
- package/dist/src/oauth/storage/file.d.ts +2 -2
- package/dist/src/oauth/storage/file.js +22 -22
- package/dist/src/oauth/storage/file.js.map +1 -1
- package/dist/src/oauth/storage/index.d.ts +5 -5
- package/dist/src/oauth/storage/memory.d.ts +2 -2
- package/dist/src/oauth/storage/memory.js +18 -18
- package/dist/src/oauth/storage/memory.js.map +1 -1
- package/dist/src/oauth/storage/postgresql.d.ts +2 -2
- package/dist/src/oauth/storage/postgresql.js +11 -11
- package/dist/src/oauth/storage/postgresql.js.map +1 -1
- package/dist/src/oauth/storage/types.d.ts +3 -3
- package/dist/src/oauth/token-context.d.ts +1 -1
- package/dist/src/oauth/token-context.js +1 -1
- package/dist/src/oauth/token-utils.d.ts +1 -1
- package/dist/src/oauth/token-utils.js +20 -20
- package/dist/src/oauth/types.d.ts +3 -3
- package/dist/src/profiles/applicator.d.ts +1 -1
- package/dist/src/profiles/applicator.js +48 -48
- package/dist/src/profiles/index.d.ts +5 -5
- package/dist/src/profiles/loader.d.ts +3 -3
- package/dist/src/profiles/loader.js +25 -25
- package/dist/src/profiles/loader.js.map +1 -1
- package/dist/src/profiles/project-loader.d.ts +1 -1
- package/dist/src/profiles/project-loader.js +23 -23
- package/dist/src/profiles/project-loader.js.map +1 -1
- package/dist/src/profiles/scope-enforcer.d.ts +2 -2
- package/dist/src/profiles/scope-enforcer.js +25 -25
- package/dist/src/profiles/scope-enforcer.js.map +1 -1
- package/dist/src/profiles/types.d.ts +2 -2
- package/dist/src/profiles/types.js +50 -48
- package/dist/src/profiles/types.js.map +1 -1
- package/dist/src/registry-manager.d.ts +19 -11
- package/dist/src/registry-manager.js +257 -172
- package/dist/src/registry-manager.js.map +1 -1
- package/dist/src/server.js +165 -149
- package/dist/src/server.js.map +1 -1
- package/dist/src/services/ConnectionManager.d.ts +33 -24
- package/dist/src/services/ConnectionManager.js +304 -179
- package/dist/src/services/ConnectionManager.js.map +1 -1
- package/dist/src/services/GitLabVersionDetector.d.ts +2 -2
- package/dist/src/services/GitLabVersionDetector.js +45 -45
- package/dist/src/services/GitLabVersionDetector.js.map +1 -1
- package/dist/src/services/HealthMonitor.d.ts +42 -0
- package/dist/src/services/HealthMonitor.js +544 -0
- package/dist/src/services/HealthMonitor.js.map +1 -0
- package/dist/src/services/InstanceConnectionPool.d.ts +2 -2
- package/dist/src/services/InstanceConnectionPool.js +13 -13
- package/dist/src/services/InstanceConnectionPool.js.map +1 -1
- package/dist/src/services/InstanceRateLimiter.js +6 -6
- package/dist/src/services/InstanceRateLimiter.js.map +1 -1
- package/dist/src/services/InstanceRegistry.d.ts +4 -5
- package/dist/src/services/InstanceRegistry.js +29 -41
- package/dist/src/services/InstanceRegistry.js.map +1 -1
- package/dist/src/services/NamespaceTierDetector.d.ts +2 -2
- package/dist/src/services/NamespaceTierDetector.js +30 -30
- package/dist/src/services/NamespaceTierDetector.js.map +1 -1
- package/dist/src/services/SchemaIntrospector.d.ts +2 -1
- package/dist/src/services/SchemaIntrospector.js +45 -42
- package/dist/src/services/SchemaIntrospector.js.map +1 -1
- package/dist/src/services/TokenScopeDetector.d.ts +4 -4
- package/dist/src/services/TokenScopeDetector.js +133 -110
- package/dist/src/services/TokenScopeDetector.js.map +1 -1
- package/dist/src/services/ToolAvailability.d.ts +15 -11
- package/dist/src/services/ToolAvailability.js +150 -130
- package/dist/src/services/ToolAvailability.js.map +1 -1
- package/dist/src/services/WidgetAvailability.d.ts +5 -5
- package/dist/src/services/WidgetAvailability.js +40 -39
- package/dist/src/services/WidgetAvailability.js.map +1 -1
- package/dist/src/session-manager.d.ts +3 -2
- package/dist/src/session-manager.js +17 -14
- package/dist/src/session-manager.js.map +1 -1
- package/dist/src/types.js +4 -4
- package/dist/src/utils/description-utils.js +4 -4
- package/dist/src/utils/description-utils.js.map +1 -1
- package/dist/src/utils/error-handler.d.ts +19 -10
- package/dist/src/utils/error-handler.js +272 -187
- package/dist/src/utils/error-handler.js.map +1 -1
- package/dist/src/utils/fetch.d.ts +7 -0
- package/dist/src/utils/fetch.js +136 -122
- package/dist/src/utils/fetch.js.map +1 -1
- package/dist/src/utils/gitlab-api.d.ts +1 -1
- package/dist/src/utils/gitlab-api.js +29 -26
- package/dist/src/utils/gitlab-api.js.map +1 -1
- package/dist/src/utils/idConversion.js +47 -47
- package/dist/src/utils/idConversion.js.map +1 -1
- package/dist/src/utils/namespace.d.ts +2 -2
- package/dist/src/utils/namespace.js +15 -15
- package/dist/src/utils/projectIdentifier.js +4 -4
- package/dist/src/utils/request-logger.d.ts +4 -4
- package/dist/src/utils/request-logger.js +5 -5
- package/dist/src/utils/schema-utils.js +24 -24
- package/dist/src/utils/schema-utils.js.map +1 -1
- package/dist/src/utils/smart-user-search.d.ts +1 -1
- package/dist/src/utils/smart-user-search.js +10 -10
- package/dist/src/utils/url.d.ts +1 -0
- package/dist/src/utils/url.js +38 -0
- package/dist/src/utils/url.js.map +1 -0
- package/dist/src/utils/version.js +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +22 -31
- package/dist/structured-world-gitlab-mcp-6.62.1.tgz +0 -0
|
@@ -9,148 +9,197 @@ const config_1 = require("../config");
|
|
|
9
9
|
const index_1 = require("../oauth/index");
|
|
10
10
|
const fetch_1 = require("../utils/fetch");
|
|
11
11
|
const logger_1 = require("../logger");
|
|
12
|
-
const
|
|
12
|
+
const InstanceRegistry_1 = require("./InstanceRegistry");
|
|
13
|
+
const url_1 = require("../utils/url");
|
|
13
14
|
class ConnectionManager {
|
|
14
15
|
static instance = null;
|
|
15
|
-
|
|
16
|
-
versionDetector = null;
|
|
17
|
-
schemaIntrospector = null;
|
|
18
|
-
instanceInfo = null;
|
|
19
|
-
schemaInfo = null;
|
|
20
|
-
tokenScopeInfo = null;
|
|
21
|
-
isInitialized = false;
|
|
16
|
+
instances = new Map();
|
|
22
17
|
currentInstanceUrl = null;
|
|
23
|
-
introspectedInstanceUrl = null;
|
|
24
18
|
introspectionPromises = new Map();
|
|
25
19
|
static introspectionCache = new Map();
|
|
26
20
|
static CACHE_TTL = 10 * 60 * 1000;
|
|
21
|
+
initializePromises = new Map();
|
|
22
|
+
latestRequestedUrl = null;
|
|
27
23
|
constructor() { }
|
|
28
24
|
static getInstance() {
|
|
29
25
|
ConnectionManager.instance ??= new ConnectionManager();
|
|
30
26
|
return ConnectionManager.instance;
|
|
31
27
|
}
|
|
32
28
|
async initialize(instanceUrl) {
|
|
33
|
-
|
|
29
|
+
const url = (0, url_1.normalizeInstanceUrl)(instanceUrl ?? config_1.GITLAB_BASE_URL);
|
|
30
|
+
this.latestRequestedUrl = url;
|
|
31
|
+
const existing = this.instances.get(url);
|
|
32
|
+
if (existing?.isInitialized) {
|
|
33
|
+
this.currentInstanceUrl = url;
|
|
34
34
|
return;
|
|
35
35
|
}
|
|
36
|
+
const inflight = this.initializePromises.get(url);
|
|
37
|
+
if (inflight) {
|
|
38
|
+
return inflight;
|
|
39
|
+
}
|
|
40
|
+
const promise = this.doInitialize(url);
|
|
41
|
+
this.initializePromises.set(url, promise);
|
|
42
|
+
try {
|
|
43
|
+
await promise;
|
|
44
|
+
const isOurPromise = this.initializePromises.get(url) === promise;
|
|
45
|
+
const initSucceeded = this.instances.get(url)?.isInitialized === true;
|
|
46
|
+
if ((isOurPromise && url === this.latestRequestedUrl) ||
|
|
47
|
+
(!this.currentInstanceUrl && initSucceeded)) {
|
|
48
|
+
this.currentInstanceUrl = url;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
if (this.initializePromises.get(url) === promise) {
|
|
53
|
+
this.initializePromises.delete(url);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async doInitialize(baseUrl) {
|
|
58
|
+
let state;
|
|
36
59
|
try {
|
|
37
60
|
const oauthMode = (0, index_1.isOAuthEnabled)();
|
|
38
|
-
const registry =
|
|
61
|
+
const registry = InstanceRegistry_1.InstanceRegistry.getInstance();
|
|
39
62
|
if (!registry.isInitialized()) {
|
|
40
63
|
await registry.initialize();
|
|
41
64
|
}
|
|
42
|
-
const baseUrl = instanceUrl ?? config_1.GITLAB_BASE_URL;
|
|
43
|
-
this.currentInstanceUrl = baseUrl;
|
|
44
65
|
if (!baseUrl) {
|
|
45
|
-
throw new Error(
|
|
66
|
+
throw new Error('GitLab base URL is required');
|
|
46
67
|
}
|
|
47
68
|
if (!oauthMode && !config_1.GITLAB_TOKEN) {
|
|
48
|
-
throw new Error(
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
69
|
+
throw new Error('GITLAB_TOKEN is required in static authentication mode. ' +
|
|
70
|
+
'Run `npx @structured-world/gitlab-mcp setup` for interactive configuration, ' +
|
|
71
|
+
'or set the environment variable and restart. ' +
|
|
72
|
+
'Docs: https://gitlab-mcp.sw.foundation/guide/quick-start');
|
|
52
73
|
}
|
|
53
74
|
const endpoint = `${baseUrl}/api/graphql`;
|
|
54
75
|
const clientOptions = oauthMode
|
|
55
76
|
? {}
|
|
56
|
-
: { headers: {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
77
|
+
: { headers: { 'PRIVATE-TOKEN': String(config_1.GITLAB_TOKEN) } };
|
|
78
|
+
const client = new client_1.GraphQLClient(endpoint, clientOptions);
|
|
79
|
+
const versionDetector = new GitLabVersionDetector_1.GitLabVersionDetector(client);
|
|
80
|
+
const schemaIntrospector = new SchemaIntrospector_1.SchemaIntrospector(client);
|
|
81
|
+
state = {
|
|
82
|
+
client,
|
|
83
|
+
versionDetector,
|
|
84
|
+
schemaIntrospector,
|
|
85
|
+
instanceInfo: null,
|
|
86
|
+
schemaInfo: null,
|
|
87
|
+
tokenScopeInfo: null,
|
|
88
|
+
isInitialized: false,
|
|
89
|
+
introspectedInstanceUrl: null,
|
|
90
|
+
};
|
|
91
|
+
this.instances.set(baseUrl, state);
|
|
60
92
|
if (oauthMode) {
|
|
61
|
-
(0, logger_1.logInfo)(
|
|
93
|
+
(0, logger_1.logInfo)('OAuth mode: attempting unauthenticated version detection');
|
|
62
94
|
try {
|
|
63
|
-
const versionResponse = await
|
|
95
|
+
const versionResponse = await (0, fetch_1.enhancedFetch)(`${baseUrl}/api/v4/version`, {
|
|
96
|
+
retry: false,
|
|
97
|
+
skipAuth: true,
|
|
98
|
+
});
|
|
64
99
|
if (versionResponse.ok) {
|
|
65
100
|
const versionData = (await versionResponse.json());
|
|
66
|
-
(0, logger_1.logInfo)(
|
|
101
|
+
(0, logger_1.logInfo)('Detected GitLab version without authentication', {
|
|
67
102
|
version: versionData.version,
|
|
68
103
|
});
|
|
69
|
-
|
|
104
|
+
state.instanceInfo = {
|
|
70
105
|
version: versionData.version,
|
|
71
|
-
tier: versionData.enterprise ?
|
|
106
|
+
tier: versionData.enterprise ? 'premium' : 'free',
|
|
72
107
|
features: this.getDefaultFeatures(versionData.enterprise ?? false),
|
|
73
108
|
detectedAt: new Date(),
|
|
74
109
|
};
|
|
75
|
-
(0, logger_1.logInfo)(
|
|
110
|
+
(0, logger_1.logInfo)('OAuth mode: version detected, full introspection deferred until first authenticated request');
|
|
76
111
|
}
|
|
77
112
|
else {
|
|
78
|
-
(0, logger_1.logInfo)(
|
|
113
|
+
(0, logger_1.logInfo)('OAuth mode: unauthenticated version detection failed, deferring all introspection', {
|
|
79
114
|
status: versionResponse.status,
|
|
80
115
|
});
|
|
81
116
|
}
|
|
82
117
|
}
|
|
83
118
|
catch (error) {
|
|
84
|
-
(0, logger_1.logInfo)(
|
|
119
|
+
(0, logger_1.logInfo)('OAuth mode: unauthenticated version detection failed, deferring all introspection', {
|
|
85
120
|
error: error instanceof Error ? error.message : String(error),
|
|
86
121
|
});
|
|
87
122
|
}
|
|
88
|
-
this.
|
|
123
|
+
if (this.instances.get(baseUrl) !== state)
|
|
124
|
+
return;
|
|
125
|
+
state.isInitialized = true;
|
|
89
126
|
return;
|
|
90
127
|
}
|
|
91
|
-
|
|
92
|
-
if (
|
|
128
|
+
state.tokenScopeInfo = await (0, TokenScopeDetector_1.detectTokenScopes)(baseUrl);
|
|
129
|
+
if (state.tokenScopeInfo) {
|
|
93
130
|
const totalTools = Object.keys((0, TokenScopeDetector_1.getToolScopeRequirements)()).length;
|
|
94
|
-
(0, TokenScopeDetector_1.logTokenScopeInfo)(
|
|
95
|
-
if (!
|
|
96
|
-
|
|
97
|
-
|
|
131
|
+
(0, TokenScopeDetector_1.logTokenScopeInfo)(state.tokenScopeInfo, totalTools, baseUrl);
|
|
132
|
+
if (!state.tokenScopeInfo.hasGraphQLAccess) {
|
|
133
|
+
state.instanceInfo = await this.detectVersionViaREST(baseUrl);
|
|
134
|
+
state.isInitialized = true;
|
|
98
135
|
return;
|
|
99
136
|
}
|
|
100
137
|
}
|
|
101
138
|
const cached = ConnectionManager.introspectionCache.get(endpoint);
|
|
102
139
|
const now = Date.now();
|
|
103
140
|
if (cached && now - cached.timestamp < ConnectionManager.CACHE_TTL) {
|
|
104
|
-
(
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
141
|
+
if (this.instances.get(baseUrl) !== state)
|
|
142
|
+
return;
|
|
143
|
+
(0, logger_1.logInfo)('Using cached GraphQL introspection data');
|
|
144
|
+
state.instanceInfo = cached.instanceInfo;
|
|
145
|
+
state.schemaInfo = cached.schemaInfo;
|
|
146
|
+
state.schemaIntrospector.rehydrate(cached.schemaInfo);
|
|
147
|
+
state.introspectedInstanceUrl = baseUrl;
|
|
108
148
|
}
|
|
109
149
|
else {
|
|
110
|
-
(0, logger_1.logDebug)(
|
|
150
|
+
(0, logger_1.logDebug)('Introspecting GitLab GraphQL schema...');
|
|
111
151
|
const [instanceInfo, schemaInfo] = await Promise.all([
|
|
112
|
-
|
|
113
|
-
|
|
152
|
+
versionDetector.detectInstance(),
|
|
153
|
+
schemaIntrospector.introspectSchema(),
|
|
114
154
|
]);
|
|
115
|
-
this.
|
|
116
|
-
|
|
117
|
-
|
|
155
|
+
if (this.instances.get(baseUrl) !== state)
|
|
156
|
+
return;
|
|
157
|
+
state.instanceInfo = instanceInfo;
|
|
158
|
+
state.schemaInfo = schemaInfo;
|
|
159
|
+
state.introspectedInstanceUrl = baseUrl;
|
|
118
160
|
ConnectionManager.introspectionCache.set(endpoint, {
|
|
119
161
|
instanceInfo,
|
|
120
162
|
schemaInfo,
|
|
121
163
|
timestamp: now,
|
|
122
164
|
});
|
|
123
|
-
(0, logger_1.logInfo)(
|
|
165
|
+
(0, logger_1.logInfo)('GraphQL schema introspection completed');
|
|
124
166
|
}
|
|
125
|
-
|
|
126
|
-
(0, logger_1.logInfo)(
|
|
127
|
-
version:
|
|
128
|
-
tier:
|
|
129
|
-
features:
|
|
130
|
-
? Object.entries(
|
|
167
|
+
state.isInitialized = true;
|
|
168
|
+
(0, logger_1.logInfo)('GitLab instance and schema detected', {
|
|
169
|
+
version: state.instanceInfo?.version,
|
|
170
|
+
tier: state.instanceInfo?.tier,
|
|
171
|
+
features: state.instanceInfo
|
|
172
|
+
? Object.entries(state.instanceInfo.features)
|
|
131
173
|
.filter(([, enabled]) => enabled)
|
|
132
174
|
.map(([feature]) => feature)
|
|
133
175
|
: [],
|
|
134
|
-
widgetTypes:
|
|
135
|
-
schemaTypes:
|
|
176
|
+
widgetTypes: state.schemaInfo?.workItemWidgetTypes.length || 0,
|
|
177
|
+
schemaTypes: state.schemaInfo?.typeDefinitions.size || 0,
|
|
136
178
|
});
|
|
137
179
|
}
|
|
138
180
|
catch (error) {
|
|
139
|
-
(
|
|
181
|
+
if (state && this.instances.get(baseUrl) === state) {
|
|
182
|
+
this.instances.delete(baseUrl);
|
|
183
|
+
}
|
|
184
|
+
(0, logger_1.logError)('Failed to initialize connection', { err: error });
|
|
140
185
|
throw error;
|
|
141
186
|
}
|
|
142
187
|
}
|
|
143
|
-
async ensureIntrospected() {
|
|
144
|
-
|
|
145
|
-
|
|
188
|
+
async ensureIntrospected(explicitUrl) {
|
|
189
|
+
const instanceUrl = (0, url_1.normalizeInstanceUrl)(explicitUrl ?? (0, index_1.getGitLabApiUrlFromContext)() ?? this.currentInstanceUrl ?? config_1.GITLAB_BASE_URL);
|
|
190
|
+
const state = this.instances.get(instanceUrl);
|
|
191
|
+
if (!state?.client || !state.versionDetector || !state.schemaIntrospector) {
|
|
192
|
+
throw new Error('Connection not initialized. Call initialize() first.');
|
|
193
|
+
}
|
|
194
|
+
if (state.instanceInfo && state.schemaInfo && state.introspectedInstanceUrl === instanceUrl) {
|
|
195
|
+
return;
|
|
146
196
|
}
|
|
147
|
-
|
|
148
|
-
if (this.instanceInfo && this.schemaInfo && this.introspectedInstanceUrl === instanceUrl) {
|
|
197
|
+
if (state.tokenScopeInfo && !state.tokenScopeInfo.hasGraphQLAccess) {
|
|
149
198
|
return;
|
|
150
199
|
}
|
|
151
200
|
const existingPromise = this.introspectionPromises.get(instanceUrl);
|
|
152
201
|
if (existingPromise) {
|
|
153
|
-
(0, logger_1.logDebug)(
|
|
202
|
+
(0, logger_1.logDebug)('Awaiting existing introspection for instance', { url: instanceUrl });
|
|
154
203
|
await existingPromise;
|
|
155
204
|
return;
|
|
156
205
|
}
|
|
@@ -160,34 +209,37 @@ class ConnectionManager {
|
|
|
160
209
|
await promise;
|
|
161
210
|
}
|
|
162
211
|
finally {
|
|
163
|
-
this.introspectionPromises.
|
|
212
|
+
if (this.introspectionPromises.get(instanceUrl) === promise) {
|
|
213
|
+
this.introspectionPromises.delete(instanceUrl);
|
|
214
|
+
}
|
|
164
215
|
}
|
|
165
216
|
}
|
|
166
217
|
async doIntrospection(instanceUrl) {
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
if (!client || !versionDet || !schemaDet) {
|
|
171
|
-
throw new Error("Connection not initialized. Call initialize() first.");
|
|
218
|
+
const state = this.instances.get(instanceUrl);
|
|
219
|
+
if (!state?.client || !state.versionDetector || !state.schemaIntrospector) {
|
|
220
|
+
throw new Error('Connection not initialized. Call initialize() first.');
|
|
172
221
|
}
|
|
222
|
+
const { client, versionDetector, schemaIntrospector } = state;
|
|
173
223
|
const endpoint = client.endpoint;
|
|
174
|
-
const registry =
|
|
224
|
+
const registry = InstanceRegistry_1.InstanceRegistry.getInstance();
|
|
175
225
|
if (registry.isInitialized()) {
|
|
176
226
|
const cachedIntrospection = registry.getIntrospection(instanceUrl);
|
|
177
227
|
if (cachedIntrospection) {
|
|
178
|
-
(0, logger_1.logInfo)(
|
|
179
|
-
|
|
228
|
+
(0, logger_1.logInfo)('Using cached introspection from InstanceRegistry', { url: instanceUrl });
|
|
229
|
+
state.instanceInfo = {
|
|
180
230
|
version: cachedIntrospection.version,
|
|
181
231
|
tier: cachedIntrospection.tier,
|
|
182
232
|
features: cachedIntrospection.features,
|
|
183
233
|
detectedAt: cachedIntrospection.cachedAt,
|
|
184
234
|
};
|
|
185
|
-
|
|
186
|
-
|
|
235
|
+
const restoredSchema = cachedIntrospection.schemaInfo;
|
|
236
|
+
state.schemaInfo = restoredSchema;
|
|
237
|
+
state.schemaIntrospector.rehydrate(restoredSchema);
|
|
238
|
+
state.introspectedInstanceUrl = instanceUrl;
|
|
187
239
|
return;
|
|
188
240
|
}
|
|
189
241
|
}
|
|
190
|
-
const primaryCacheKey = instanceUrl
|
|
242
|
+
const primaryCacheKey = instanceUrl;
|
|
191
243
|
const legacyCacheKey = endpoint;
|
|
192
244
|
let cached = ConnectionManager.introspectionCache.get(primaryCacheKey);
|
|
193
245
|
if (!cached && primaryCacheKey !== legacyCacheKey) {
|
|
@@ -195,30 +247,23 @@ class ConnectionManager {
|
|
|
195
247
|
}
|
|
196
248
|
const now = Date.now();
|
|
197
249
|
if (cached && now - cached.timestamp < ConnectionManager.CACHE_TTL) {
|
|
198
|
-
(0, logger_1.logInfo)(
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
250
|
+
(0, logger_1.logInfo)('Using cached GraphQL introspection data');
|
|
251
|
+
state.instanceInfo = cached.instanceInfo;
|
|
252
|
+
state.schemaInfo = cached.schemaInfo;
|
|
253
|
+
state.schemaIntrospector.rehydrate(cached.schemaInfo);
|
|
254
|
+
state.introspectedInstanceUrl = instanceUrl;
|
|
202
255
|
return;
|
|
203
256
|
}
|
|
204
|
-
(0, logger_1.logDebug)(
|
|
205
|
-
let versionDetector = versionDet;
|
|
206
|
-
let schemaIntrospector = schemaDet;
|
|
207
|
-
if (registry.isInitialized() && instanceUrl !== this.currentInstanceUrl) {
|
|
208
|
-
const instanceClient = this.getInstanceClient(instanceUrl);
|
|
209
|
-
if (instanceClient !== client) {
|
|
210
|
-
versionDetector = new GitLabVersionDetector_1.GitLabVersionDetector(instanceClient);
|
|
211
|
-
schemaIntrospector = new SchemaIntrospector_1.SchemaIntrospector(instanceClient);
|
|
212
|
-
(0, logger_1.logDebug)("Using per-instance detectors for introspection", { instanceUrl });
|
|
213
|
-
}
|
|
214
|
-
}
|
|
257
|
+
(0, logger_1.logDebug)('Introspecting GitLab GraphQL schema (deferred OAuth mode)...');
|
|
215
258
|
const [instanceInfo, schemaInfo] = await Promise.all([
|
|
216
259
|
versionDetector.detectInstance(),
|
|
217
260
|
schemaIntrospector.introspectSchema(),
|
|
218
261
|
]);
|
|
219
|
-
this.
|
|
220
|
-
|
|
221
|
-
|
|
262
|
+
if (this.instances.get(instanceUrl) !== state)
|
|
263
|
+
return;
|
|
264
|
+
state.instanceInfo = instanceInfo;
|
|
265
|
+
state.schemaInfo = schemaInfo;
|
|
266
|
+
state.introspectedInstanceUrl = instanceUrl;
|
|
222
267
|
ConnectionManager.introspectionCache.set(primaryCacheKey, {
|
|
223
268
|
instanceInfo,
|
|
224
269
|
schemaInfo,
|
|
@@ -234,105 +279,147 @@ class ConnectionManager {
|
|
|
234
279
|
};
|
|
235
280
|
registry.setIntrospection(instanceUrl, cachedIntrospection);
|
|
236
281
|
}
|
|
237
|
-
(0, logger_1.logInfo)(
|
|
238
|
-
version:
|
|
239
|
-
tier:
|
|
240
|
-
widgetTypes:
|
|
282
|
+
(0, logger_1.logInfo)('GraphQL schema introspection completed (deferred)', {
|
|
283
|
+
version: state.instanceInfo?.version,
|
|
284
|
+
tier: state.instanceInfo?.tier,
|
|
285
|
+
widgetTypes: state.schemaInfo?.workItemWidgetTypes.length || 0,
|
|
241
286
|
});
|
|
242
287
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
288
|
+
resolveState(instanceUrl) {
|
|
289
|
+
const url = instanceUrl ? (0, url_1.normalizeInstanceUrl)(instanceUrl) : this.currentInstanceUrl;
|
|
290
|
+
if (!url) {
|
|
291
|
+
throw new Error('Connection not initialized. Call initialize() first.');
|
|
292
|
+
}
|
|
293
|
+
const state = this.instances.get(url);
|
|
294
|
+
if (!state) {
|
|
295
|
+
throw new Error(`Connection not initialized for ${url}. Call initialize() first.`);
|
|
246
296
|
}
|
|
247
|
-
return
|
|
297
|
+
return [state, url];
|
|
298
|
+
}
|
|
299
|
+
getClient(instanceUrl) {
|
|
300
|
+
const [state] = this.resolveState(instanceUrl);
|
|
301
|
+
return state.client;
|
|
248
302
|
}
|
|
249
303
|
getInstanceClient(instanceUrl, authHeaders) {
|
|
250
|
-
const registry =
|
|
251
|
-
const
|
|
304
|
+
const registry = InstanceRegistry_1.InstanceRegistry.getInstance();
|
|
305
|
+
const rawTargetUrl = instanceUrl ?? (0, index_1.getGitLabApiUrlFromContext)() ?? this.currentInstanceUrl;
|
|
306
|
+
const targetUrl = rawTargetUrl ? (0, url_1.normalizeInstanceUrl)(rawTargetUrl) : null;
|
|
252
307
|
if (targetUrl && registry.isInitialized() && registry.has(targetUrl)) {
|
|
253
308
|
const client = registry.getGraphQLClient(targetUrl, authHeaders);
|
|
254
309
|
if (client) {
|
|
255
310
|
return client;
|
|
256
311
|
}
|
|
257
312
|
}
|
|
258
|
-
if (
|
|
259
|
-
|
|
313
|
+
if (targetUrl) {
|
|
314
|
+
const state = this.instances.get(targetUrl);
|
|
315
|
+
if (state)
|
|
316
|
+
return state.client;
|
|
317
|
+
throw new Error(`Connection not initialized for ${targetUrl}. Call initialize() first.`);
|
|
260
318
|
}
|
|
261
|
-
return this.
|
|
319
|
+
return this.getClient();
|
|
262
320
|
}
|
|
263
|
-
getVersionDetector() {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
}
|
|
267
|
-
return this.versionDetector;
|
|
321
|
+
getVersionDetector(instanceUrl) {
|
|
322
|
+
const [state] = this.resolveState(instanceUrl);
|
|
323
|
+
return state.versionDetector;
|
|
268
324
|
}
|
|
269
|
-
getSchemaIntrospector() {
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
}
|
|
273
|
-
return this.schemaIntrospector;
|
|
325
|
+
getSchemaIntrospector(instanceUrl) {
|
|
326
|
+
const [state] = this.resolveState(instanceUrl);
|
|
327
|
+
return state.schemaIntrospector;
|
|
274
328
|
}
|
|
275
|
-
getInstanceInfo() {
|
|
276
|
-
|
|
277
|
-
|
|
329
|
+
getInstanceInfo(instanceUrl) {
|
|
330
|
+
const [state, resolvedUrl] = this.resolveState(instanceUrl);
|
|
331
|
+
if (!state.instanceInfo) {
|
|
332
|
+
throw new Error(`Instance information is not available for ${resolvedUrl}. Initialization may have completed without version detection (OAuth deferred/REST-only mode).`);
|
|
278
333
|
}
|
|
279
|
-
return
|
|
334
|
+
return state.instanceInfo;
|
|
280
335
|
}
|
|
281
|
-
getSchemaInfo() {
|
|
282
|
-
|
|
283
|
-
|
|
336
|
+
getSchemaInfo(instanceUrl) {
|
|
337
|
+
const [state, resolvedUrl] = this.resolveState(instanceUrl);
|
|
338
|
+
if (!state.schemaInfo) {
|
|
339
|
+
throw new Error(`Schema information is not available for ${resolvedUrl}. Initialization may have completed without schema introspection.`);
|
|
284
340
|
}
|
|
285
|
-
return
|
|
341
|
+
return state.schemaInfo;
|
|
286
342
|
}
|
|
287
343
|
getCurrentInstanceUrl() {
|
|
288
344
|
return this.currentInstanceUrl;
|
|
289
345
|
}
|
|
290
|
-
|
|
291
|
-
|
|
346
|
+
isConnected(instanceUrl) {
|
|
347
|
+
const url = instanceUrl ? (0, url_1.normalizeInstanceUrl)(instanceUrl) : this.currentInstanceUrl;
|
|
348
|
+
if (!url)
|
|
292
349
|
return false;
|
|
293
|
-
|
|
294
|
-
return
|
|
350
|
+
const state = this.instances.get(url);
|
|
351
|
+
return state?.isInitialized ?? false;
|
|
295
352
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
353
|
+
isFeatureAvailable(feature, instanceUrl) {
|
|
354
|
+
const url = instanceUrl ? (0, url_1.normalizeInstanceUrl)(instanceUrl) : this.currentInstanceUrl;
|
|
355
|
+
if (!url)
|
|
356
|
+
return false;
|
|
357
|
+
const state = this.instances.get(url);
|
|
358
|
+
if (!state?.instanceInfo)
|
|
359
|
+
return false;
|
|
360
|
+
return state.instanceInfo.features[feature];
|
|
301
361
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
362
|
+
getTier(instanceUrl) {
|
|
363
|
+
const url = instanceUrl ? (0, url_1.normalizeInstanceUrl)(instanceUrl) : this.currentInstanceUrl;
|
|
364
|
+
if (!url)
|
|
365
|
+
return 'unknown';
|
|
366
|
+
const state = this.instances.get(url);
|
|
367
|
+
if (!state?.instanceInfo)
|
|
368
|
+
return 'unknown';
|
|
369
|
+
return state.instanceInfo.tier;
|
|
307
370
|
}
|
|
308
|
-
|
|
309
|
-
|
|
371
|
+
getVersion(instanceUrl) {
|
|
372
|
+
const url = instanceUrl ? (0, url_1.normalizeInstanceUrl)(instanceUrl) : this.currentInstanceUrl;
|
|
373
|
+
if (!url)
|
|
374
|
+
return 'unknown';
|
|
375
|
+
const state = this.instances.get(url);
|
|
376
|
+
if (!state?.instanceInfo)
|
|
377
|
+
return 'unknown';
|
|
378
|
+
return state.instanceInfo.version;
|
|
379
|
+
}
|
|
380
|
+
isWidgetAvailable(widgetType, instanceUrl) {
|
|
381
|
+
const url = instanceUrl ? (0, url_1.normalizeInstanceUrl)(instanceUrl) : this.currentInstanceUrl;
|
|
382
|
+
if (!url)
|
|
310
383
|
return false;
|
|
311
|
-
|
|
312
|
-
return
|
|
384
|
+
const state = this.instances.get(url);
|
|
385
|
+
return state?.schemaInfo?.workItemWidgetTypes.includes(widgetType) ?? false;
|
|
313
386
|
}
|
|
314
|
-
getTokenScopeInfo() {
|
|
315
|
-
|
|
387
|
+
getTokenScopeInfo(instanceUrl) {
|
|
388
|
+
const url = instanceUrl ? (0, url_1.normalizeInstanceUrl)(instanceUrl) : this.currentInstanceUrl;
|
|
389
|
+
if (!url)
|
|
390
|
+
return null;
|
|
391
|
+
const state = this.instances.get(url);
|
|
392
|
+
return state?.tokenScopeInfo ?? null;
|
|
316
393
|
}
|
|
317
394
|
async refreshTokenScopes() {
|
|
318
395
|
if ((0, index_1.isOAuthEnabled)()) {
|
|
319
396
|
return false;
|
|
320
397
|
}
|
|
321
|
-
const
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
const
|
|
398
|
+
const url = this.currentInstanceUrl;
|
|
399
|
+
if (!url)
|
|
400
|
+
return false;
|
|
401
|
+
const state = this.instances.get(url);
|
|
402
|
+
if (!state)
|
|
403
|
+
return false;
|
|
404
|
+
const previousScopes = state.tokenScopeInfo?.scopes ?? [];
|
|
405
|
+
const previousHasGraphQL = state.tokenScopeInfo?.hasGraphQLAccess ?? false;
|
|
406
|
+
const previousHasWrite = state.tokenScopeInfo?.hasWriteAccess ?? false;
|
|
407
|
+
const newScopeInfo = await (0, TokenScopeDetector_1.detectTokenScopes)(url);
|
|
325
408
|
if (!newScopeInfo) {
|
|
326
409
|
return false;
|
|
327
410
|
}
|
|
328
411
|
const newScopes = newScopeInfo.scopes;
|
|
329
412
|
const scopesChanged = previousScopes.length !== newScopes.length ||
|
|
330
|
-
!previousScopes.every(s => newScopes.includes(s)) ||
|
|
413
|
+
!previousScopes.every((s) => newScopes.includes(s)) ||
|
|
331
414
|
previousHasGraphQL !== newScopeInfo.hasGraphQLAccess ||
|
|
332
415
|
previousHasWrite !== newScopeInfo.hasWriteAccess;
|
|
416
|
+
const currentState = this.instances.get(url);
|
|
417
|
+
if (currentState !== state) {
|
|
418
|
+
return false;
|
|
419
|
+
}
|
|
420
|
+
state.tokenScopeInfo = newScopeInfo;
|
|
333
421
|
if (scopesChanged) {
|
|
334
|
-
|
|
335
|
-
(0, logger_1.logInfo)("Token scopes changed - tool registry will be refreshed", {
|
|
422
|
+
(0, logger_1.logInfo)('Token scopes changed - tool registry will be refreshed', {
|
|
336
423
|
previousScopes,
|
|
337
424
|
newScopes,
|
|
338
425
|
hasGraphQLAccess: newScopeInfo.hasGraphQLAccess,
|
|
@@ -341,39 +428,39 @@ class ConnectionManager {
|
|
|
341
428
|
}
|
|
342
429
|
return scopesChanged;
|
|
343
430
|
}
|
|
344
|
-
async detectVersionViaREST() {
|
|
431
|
+
async detectVersionViaREST(baseUrl) {
|
|
345
432
|
try {
|
|
346
|
-
const
|
|
347
|
-
const response = await (0, fetch_1.enhancedFetch)(`${
|
|
433
|
+
const url = baseUrl ?? this.currentInstanceUrl ?? config_1.GITLAB_BASE_URL;
|
|
434
|
+
const response = await (0, fetch_1.enhancedFetch)(`${url}/api/v4/version`, {
|
|
348
435
|
headers: {
|
|
349
|
-
|
|
350
|
-
Accept:
|
|
436
|
+
'PRIVATE-TOKEN': config_1.GITLAB_TOKEN ?? '',
|
|
437
|
+
Accept: 'application/json',
|
|
351
438
|
},
|
|
352
439
|
retry: false,
|
|
353
440
|
});
|
|
354
441
|
if (response.ok) {
|
|
355
442
|
const data = (await response.json());
|
|
356
|
-
(0, logger_1.logInfo)(
|
|
443
|
+
(0, logger_1.logInfo)('Detected GitLab version via REST (GraphQL unavailable)', {
|
|
357
444
|
version: data.version,
|
|
358
445
|
enterprise: data.enterprise,
|
|
359
446
|
});
|
|
360
447
|
return {
|
|
361
448
|
version: data.version,
|
|
362
|
-
tier: data.enterprise ?
|
|
449
|
+
tier: data.enterprise ? 'premium' : 'free',
|
|
363
450
|
features: this.getDefaultFeatures(data.enterprise ?? false),
|
|
364
451
|
detectedAt: new Date(),
|
|
365
452
|
};
|
|
366
453
|
}
|
|
367
|
-
(0, logger_1.logInfo)(
|
|
454
|
+
(0, logger_1.logInfo)('REST version detection failed, using defaults', { status: response.status });
|
|
368
455
|
}
|
|
369
456
|
catch (error) {
|
|
370
|
-
(0, logger_1.logInfo)(
|
|
457
|
+
(0, logger_1.logInfo)('REST version detection failed, using defaults', {
|
|
371
458
|
error: error instanceof Error ? error.message : String(error),
|
|
372
459
|
});
|
|
373
460
|
}
|
|
374
461
|
return {
|
|
375
|
-
version:
|
|
376
|
-
tier:
|
|
462
|
+
version: 'unknown',
|
|
463
|
+
tier: 'free',
|
|
377
464
|
features: this.getDefaultFeatures(false),
|
|
378
465
|
detectedAt: new Date(),
|
|
379
466
|
};
|
|
@@ -407,31 +494,69 @@ class ConnectionManager {
|
|
|
407
494
|
emailParticipants: true,
|
|
408
495
|
};
|
|
409
496
|
}
|
|
410
|
-
async reinitialize(
|
|
411
|
-
(0,
|
|
497
|
+
async reinitialize(rawInstanceUrl) {
|
|
498
|
+
const newInstanceUrl = (0, url_1.normalizeInstanceUrl)(rawInstanceUrl);
|
|
499
|
+
(0, logger_1.logInfo)('Re-initializing ConnectionManager for new instance', {
|
|
412
500
|
newInstanceUrl,
|
|
413
501
|
});
|
|
414
|
-
this.
|
|
415
|
-
const
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
(
|
|
419
|
-
|
|
420
|
-
|
|
502
|
+
const previousUrl = this.currentInstanceUrl;
|
|
503
|
+
const savedState = this.instances.get(newInstanceUrl);
|
|
504
|
+
const restorableState = savedState?.isInitialized ? savedState : undefined;
|
|
505
|
+
this.initializePromises.delete(newInstanceUrl);
|
|
506
|
+
this.introspectionPromises.delete(newInstanceUrl);
|
|
507
|
+
this.instances.delete(newInstanceUrl);
|
|
508
|
+
try {
|
|
509
|
+
const registry = InstanceRegistry_1.InstanceRegistry.getInstance();
|
|
510
|
+
registry.clearIntrospectionCache(newInstanceUrl);
|
|
511
|
+
}
|
|
512
|
+
catch {
|
|
513
|
+
}
|
|
514
|
+
ConnectionManager.introspectionCache.delete(newInstanceUrl);
|
|
515
|
+
ConnectionManager.introspectionCache.delete(`${newInstanceUrl}/api/graphql`);
|
|
516
|
+
try {
|
|
517
|
+
await this.initialize(newInstanceUrl);
|
|
518
|
+
}
|
|
519
|
+
catch (error) {
|
|
520
|
+
if (restorableState) {
|
|
521
|
+
this.instances.set(newInstanceUrl, restorableState);
|
|
522
|
+
}
|
|
523
|
+
if (previousUrl && this.instances.has(previousUrl)) {
|
|
524
|
+
this.currentInstanceUrl = previousUrl;
|
|
525
|
+
}
|
|
526
|
+
else if (restorableState) {
|
|
527
|
+
this.currentInstanceUrl = newInstanceUrl;
|
|
528
|
+
}
|
|
529
|
+
throw error;
|
|
530
|
+
}
|
|
531
|
+
if (previousUrl && previousUrl !== newInstanceUrl) {
|
|
532
|
+
this.initializePromises.delete(previousUrl);
|
|
533
|
+
this.introspectionPromises.delete(previousUrl);
|
|
534
|
+
this.instances.delete(previousUrl);
|
|
535
|
+
}
|
|
536
|
+
const state = this.instances.get(newInstanceUrl);
|
|
537
|
+
(0, logger_1.logInfo)('ConnectionManager re-initialized', {
|
|
538
|
+
version: state?.instanceInfo?.version,
|
|
539
|
+
tier: state?.instanceInfo?.tier,
|
|
421
540
|
instanceUrl: this.currentInstanceUrl,
|
|
422
541
|
});
|
|
423
542
|
}
|
|
543
|
+
clearInflight(rawUrl) {
|
|
544
|
+
const url = (0, url_1.normalizeInstanceUrl)(rawUrl);
|
|
545
|
+
this.initializePromises.delete(url);
|
|
546
|
+
this.introspectionPromises.delete(url);
|
|
547
|
+
}
|
|
424
548
|
reset() {
|
|
425
|
-
this.
|
|
426
|
-
this.versionDetector = null;
|
|
427
|
-
this.schemaIntrospector = null;
|
|
428
|
-
this.instanceInfo = null;
|
|
429
|
-
this.schemaInfo = null;
|
|
430
|
-
this.tokenScopeInfo = null;
|
|
549
|
+
this.instances.clear();
|
|
431
550
|
this.currentInstanceUrl = null;
|
|
432
|
-
this.
|
|
551
|
+
this.latestRequestedUrl = null;
|
|
433
552
|
this.introspectionPromises.clear();
|
|
434
|
-
this.
|
|
553
|
+
this.initializePromises.clear();
|
|
554
|
+
ConnectionManager.introspectionCache.clear();
|
|
555
|
+
try {
|
|
556
|
+
InstanceRegistry_1.InstanceRegistry.getInstance().clearIntrospectionCache();
|
|
557
|
+
}
|
|
558
|
+
catch {
|
|
559
|
+
}
|
|
435
560
|
}
|
|
436
561
|
}
|
|
437
562
|
exports.ConnectionManager = ConnectionManager;
|