@gitkraken/core-gitlens 0.3.1 → 0.4.0

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.
Files changed (230) hide show
  1. package/CHANGELOG.md +13 -1
  2. package/README.md +13 -10
  3. package/dist/git/context.d.ts +4 -3
  4. package/dist/git/context.d.ts.map +1 -1
  5. package/dist/git/context.js.map +1 -1
  6. package/dist/git/providers/operations.d.ts +1 -0
  7. package/dist/git/providers/operations.d.ts.map +1 -1
  8. package/dist/git/providers/worktrees.d.ts +2 -0
  9. package/dist/git/providers/worktrees.d.ts.map +1 -1
  10. package/dist/git/utils/conflictResolution.utils.d.ts +32 -0
  11. package/dist/git/utils/conflictResolution.utils.d.ts.map +1 -1
  12. package/dist/git/utils/conflictResolution.utils.js +95 -0
  13. package/dist/git/utils/conflictResolution.utils.js.map +1 -1
  14. package/dist/git-cli/providers/operations.d.ts +1 -0
  15. package/dist/git-cli/providers/operations.d.ts.map +1 -1
  16. package/dist/git-cli/providers/operations.js +22 -1
  17. package/dist/git-cli/providers/operations.js.map +1 -1
  18. package/dist/git-cli/providers/worktrees.d.ts +2 -0
  19. package/dist/git-cli/providers/worktrees.d.ts.map +1 -1
  20. package/dist/git-cli/providers/worktrees.js +3 -0
  21. package/dist/git-cli/providers/worktrees.js.map +1 -1
  22. package/dist/plus/ai/utils/ai.utils.js +5 -5
  23. package/dist/plus/ai/utils/ai.utils.js.map +1 -1
  24. package/dist/plus/git-github/api/github.d.ts +6 -13
  25. package/dist/plus/git-github/api/github.d.ts.map +1 -1
  26. package/dist/plus/git-github/api/github.js +5 -10
  27. package/dist/plus/git-github/api/github.js.map +1 -1
  28. package/dist/plus/integrations/authentication/cloudIntegrationService.d.ts +11 -0
  29. package/dist/plus/integrations/authentication/cloudIntegrationService.d.ts.map +1 -0
  30. package/dist/plus/integrations/authentication/cloudIntegrationService.js +90 -0
  31. package/dist/plus/integrations/authentication/cloudIntegrationService.js.map +1 -0
  32. package/dist/plus/integrations/authentication/configuredIntegrationService.d.ts +67 -0
  33. package/dist/plus/integrations/authentication/configuredIntegrationService.d.ts.map +1 -0
  34. package/dist/plus/integrations/authentication/configuredIntegrationService.js +295 -0
  35. package/dist/plus/integrations/authentication/configuredIntegrationService.js.map +1 -0
  36. package/dist/plus/integrations/authentication/integrationAuthenticationProvider.d.ts +92 -0
  37. package/dist/plus/integrations/authentication/integrationAuthenticationProvider.d.ts.map +1 -0
  38. package/dist/plus/integrations/authentication/integrationAuthenticationProvider.js +185 -0
  39. package/dist/plus/integrations/authentication/integrationAuthenticationProvider.js.map +1 -0
  40. package/dist/plus/integrations/authentication/integrationAuthenticationService.d.ts +62 -0
  41. package/dist/plus/integrations/authentication/integrationAuthenticationService.d.ts.map +1 -0
  42. package/dist/plus/integrations/authentication/integrationAuthenticationService.js +122 -0
  43. package/dist/plus/integrations/authentication/integrationAuthenticationService.js.map +1 -0
  44. package/dist/plus/integrations/authentication/manualTokenProvider.d.ts +15 -0
  45. package/dist/plus/integrations/authentication/manualTokenProvider.d.ts.map +1 -0
  46. package/dist/plus/integrations/authentication/manualTokenProvider.js +49 -0
  47. package/dist/plus/integrations/authentication/manualTokenProvider.js.map +1 -0
  48. package/dist/plus/integrations/authentication/models.d.ts +87 -0
  49. package/dist/plus/integrations/authentication/models.d.ts.map +1 -0
  50. package/dist/plus/integrations/authentication/models.js +64 -0
  51. package/dist/plus/integrations/authentication/models.js.map +1 -0
  52. package/dist/plus/integrations/constants.d.ts +47 -0
  53. package/dist/plus/integrations/constants.d.ts.map +1 -0
  54. package/dist/plus/integrations/constants.js +128 -0
  55. package/dist/plus/integrations/constants.js.map +1 -0
  56. package/dist/plus/integrations/context.d.ts +354 -0
  57. package/dist/plus/integrations/context.d.ts.map +1 -0
  58. package/dist/plus/integrations/context.js +2 -0
  59. package/dist/plus/integrations/context.js.map +1 -0
  60. package/dist/plus/integrations/errors.d.ts +14 -0
  61. package/dist/plus/integrations/errors.d.ts.map +1 -0
  62. package/dist/plus/integrations/errors.js +19 -0
  63. package/dist/plus/integrations/errors.js.map +1 -0
  64. package/dist/plus/integrations/index.d.ts +32 -0
  65. package/dist/plus/integrations/index.d.ts.map +1 -0
  66. package/dist/plus/integrations/index.js +62 -0
  67. package/dist/plus/integrations/index.js.map +1 -0
  68. package/dist/plus/integrations/integrationService.d.ts +98 -0
  69. package/dist/plus/integrations/integrationService.d.ts.map +1 -0
  70. package/dist/plus/integrations/integrationService.js +627 -0
  71. package/dist/plus/integrations/integrationService.js.map +1 -0
  72. package/dist/plus/integrations/models/gitHostIntegration.d.ts +82 -0
  73. package/dist/plus/integrations/models/gitHostIntegration.d.ts.map +1 -0
  74. package/dist/plus/integrations/models/gitHostIntegration.js +522 -0
  75. package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -0
  76. package/dist/plus/integrations/models/integration.d.ts +127 -0
  77. package/dist/plus/integrations/models/integration.d.ts.map +1 -0
  78. package/dist/plus/integrations/models/integration.js +456 -0
  79. package/dist/plus/integrations/models/integration.js.map +1 -0
  80. package/dist/plus/integrations/models/issuesIntegration.d.ts +28 -0
  81. package/dist/plus/integrations/models/issuesIntegration.d.ts.map +1 -0
  82. package/dist/plus/integrations/models/issuesIntegration.js +101 -0
  83. package/dist/plus/integrations/models/issuesIntegration.js.map +1 -0
  84. package/dist/plus/integrations/providers/apiClients.d.ts +25 -0
  85. package/dist/plus/integrations/providers/apiClients.d.ts.map +1 -0
  86. package/dist/plus/integrations/providers/apiClients.js +39 -0
  87. package/dist/plus/integrations/providers/apiClients.js.map +1 -0
  88. package/dist/plus/integrations/providers/azure/azure.d.ts +47 -0
  89. package/dist/plus/integrations/providers/azure/azure.d.ts.map +1 -0
  90. package/dist/plus/integrations/providers/azure/azure.js +444 -0
  91. package/dist/plus/integrations/providers/azure/azure.js.map +1 -0
  92. package/dist/plus/integrations/providers/azure/models.d.ts +286 -0
  93. package/dist/plus/integrations/providers/azure/models.d.ts.map +1 -0
  94. package/dist/plus/integrations/providers/azure/models.js +203 -0
  95. package/dist/plus/integrations/providers/azure/models.js.map +1 -0
  96. package/dist/plus/integrations/providers/azureDevOps.d.ts +95 -0
  97. package/dist/plus/integrations/providers/azureDevOps.d.ts.map +1 -0
  98. package/dist/plus/integrations/providers/azureDevOps.js +432 -0
  99. package/dist/plus/integrations/providers/azureDevOps.js.map +1 -0
  100. package/dist/plus/integrations/providers/bitbucket/bitbucket.d.ts +42 -0
  101. package/dist/plus/integrations/providers/bitbucket/bitbucket.d.ts.map +1 -0
  102. package/dist/plus/integrations/providers/bitbucket/bitbucket.js +513 -0
  103. package/dist/plus/integrations/providers/bitbucket/bitbucket.js.map +1 -0
  104. package/dist/plus/integrations/providers/bitbucket/models.d.ts +222 -0
  105. package/dist/plus/integrations/providers/bitbucket/models.d.ts.map +1 -0
  106. package/dist/plus/integrations/providers/bitbucket/models.js +158 -0
  107. package/dist/plus/integrations/providers/bitbucket/models.js.map +1 -0
  108. package/dist/plus/integrations/providers/bitbucket-server/models.d.ts +120 -0
  109. package/dist/plus/integrations/providers/bitbucket-server/models.d.ts.map +1 -0
  110. package/dist/plus/integrations/providers/bitbucket-server/models.js +111 -0
  111. package/dist/plus/integrations/providers/bitbucket-server/models.js.map +1 -0
  112. package/dist/plus/integrations/providers/bitbucket-server.d.ts +60 -0
  113. package/dist/plus/integrations/providers/bitbucket-server.d.ts.map +1 -0
  114. package/dist/plus/integrations/providers/bitbucket-server.js +138 -0
  115. package/dist/plus/integrations/providers/bitbucket-server.js.map +1 -0
  116. package/dist/plus/integrations/providers/bitbucket.d.ts +50 -0
  117. package/dist/plus/integrations/providers/bitbucket.d.ts.map +1 -0
  118. package/dist/plus/integrations/providers/bitbucket.js +181 -0
  119. package/dist/plus/integrations/providers/bitbucket.js.map +1 -0
  120. package/dist/plus/integrations/providers/github/github.d.ts +5 -0
  121. package/dist/plus/integrations/providers/github/github.d.ts.map +1 -0
  122. package/dist/plus/integrations/providers/github/github.js +47 -0
  123. package/dist/plus/integrations/providers/github/github.js.map +1 -0
  124. package/dist/plus/integrations/providers/github/github.utils.d.ts +11 -0
  125. package/dist/plus/integrations/providers/github/github.utils.d.ts.map +1 -0
  126. package/dist/plus/integrations/providers/github/github.utils.js +6 -0
  127. package/dist/plus/integrations/providers/github/github.utils.js.map +1 -0
  128. package/dist/plus/integrations/providers/github/models.d.ts +3 -0
  129. package/dist/plus/integrations/providers/github/models.d.ts.map +1 -0
  130. package/dist/plus/integrations/providers/github/models.js +2 -0
  131. package/dist/plus/integrations/providers/github/models.js.map +1 -0
  132. package/dist/plus/integrations/providers/github.d.ts +73 -0
  133. package/dist/plus/integrations/providers/github.d.ts.map +1 -0
  134. package/dist/plus/integrations/providers/github.js +160 -0
  135. package/dist/plus/integrations/providers/github.js.map +1 -0
  136. package/dist/plus/integrations/providers/gitlab/gitlab.d.ts +63 -0
  137. package/dist/plus/integrations/providers/gitlab/gitlab.d.ts.map +1 -0
  138. package/dist/plus/integrations/providers/gitlab/gitlab.js +828 -0
  139. package/dist/plus/integrations/providers/gitlab/gitlab.js.map +1 -0
  140. package/dist/plus/integrations/providers/gitlab/gitlab.utils.d.ts +21 -0
  141. package/dist/plus/integrations/providers/gitlab/gitlab.utils.d.ts.map +1 -0
  142. package/dist/plus/integrations/providers/gitlab/gitlab.utils.js +45 -0
  143. package/dist/plus/integrations/providers/gitlab/gitlab.utils.js.map +1 -0
  144. package/dist/plus/integrations/providers/gitlab/models.d.ts +128 -0
  145. package/dist/plus/integrations/providers/gitlab/models.d.ts.map +1 -0
  146. package/dist/plus/integrations/providers/gitlab/models.js +96 -0
  147. package/dist/plus/integrations/providers/gitlab/models.js.map +1 -0
  148. package/dist/plus/integrations/providers/gitlab.d.ts +79 -0
  149. package/dist/plus/integrations/providers/gitlab.d.ts.map +1 -0
  150. package/dist/plus/integrations/providers/gitlab.js +253 -0
  151. package/dist/plus/integrations/providers/gitlab.js.map +1 -0
  152. package/dist/plus/integrations/providers/jira.d.ts +46 -0
  153. package/dist/plus/integrations/providers/jira.d.ts.map +1 -0
  154. package/dist/plus/integrations/providers/jira.js +255 -0
  155. package/dist/plus/integrations/providers/jira.js.map +1 -0
  156. package/dist/plus/integrations/providers/linear.d.ts +47 -0
  157. package/dist/plus/integrations/providers/linear.d.ts.map +1 -0
  158. package/dist/plus/integrations/providers/linear.js +198 -0
  159. package/dist/plus/integrations/providers/linear.js.map +1 -0
  160. package/dist/plus/integrations/providers/models.d.ts +433 -0
  161. package/dist/plus/integrations/providers/models.d.ts.map +1 -0
  162. package/dist/plus/integrations/providers/models.js +602 -0
  163. package/dist/plus/integrations/providers/models.js.map +1 -0
  164. package/dist/plus/integrations/providers/providersApi.d.ts +129 -0
  165. package/dist/plus/integrations/providers/providersApi.d.ts.map +1 -0
  166. package/dist/plus/integrations/providers/providersApi.js +602 -0
  167. package/dist/plus/integrations/providers/providersApi.js.map +1 -0
  168. package/dist/plus/integrations/providers/utils.d.ts +54 -0
  169. package/dist/plus/integrations/providers/utils.d.ts.map +1 -0
  170. package/dist/plus/integrations/providers/utils.js +262 -0
  171. package/dist/plus/integrations/providers/utils.js.map +1 -0
  172. package/dist/plus/integrations/telemetry.d.ts +26 -0
  173. package/dist/plus/integrations/telemetry.d.ts.map +1 -0
  174. package/dist/plus/integrations/telemetry.js +11 -0
  175. package/dist/plus/integrations/telemetry.js.map +1 -0
  176. package/dist/plus/integrations/utils/integration.utils.d.ts +14 -0
  177. package/dist/plus/integrations/utils/integration.utils.d.ts.map +1 -0
  178. package/dist/plus/integrations/utils/integration.utils.js +111 -0
  179. package/dist/plus/integrations/utils/integration.utils.js.map +1 -0
  180. package/dist/utils/disposable.d.ts +15 -2
  181. package/dist/utils/disposable.d.ts.map +1 -1
  182. package/dist/utils/disposable.js.map +1 -1
  183. package/package.json +43 -2
  184. package/src/git/context.ts +4 -3
  185. package/src/git/providers/operations.ts +1 -1
  186. package/src/git/providers/worktrees.ts +14 -2
  187. package/src/git/utils/conflictResolution.utils.ts +126 -0
  188. package/src/git-cli/providers/operations.ts +22 -2
  189. package/src/git-cli/providers/worktrees.ts +17 -2
  190. package/src/plus/ai/utils/ai.utils.ts +5 -5
  191. package/src/plus/git-github/api/github.ts +13 -25
  192. package/src/plus/integrations/authentication/cloudIntegrationService.ts +120 -0
  193. package/src/plus/integrations/authentication/configuredIntegrationService.ts +414 -0
  194. package/src/plus/integrations/authentication/integrationAuthenticationProvider.ts +289 -0
  195. package/src/plus/integrations/authentication/integrationAuthenticationService.ts +144 -0
  196. package/src/plus/integrations/authentication/manualTokenProvider.ts +72 -0
  197. package/src/plus/integrations/authentication/models.ts +168 -0
  198. package/src/plus/integrations/constants.ts +169 -0
  199. package/src/plus/integrations/context.ts +383 -0
  200. package/src/plus/integrations/errors.ts +35 -0
  201. package/src/plus/integrations/index.ts +119 -0
  202. package/src/plus/integrations/integrationService.ts +924 -0
  203. package/src/plus/integrations/models/gitHostIntegration.ts +738 -0
  204. package/src/plus/integrations/models/integration.ts +657 -0
  205. package/src/plus/integrations/models/issuesIntegration.ts +124 -0
  206. package/src/plus/integrations/providers/apiClients.ts +72 -0
  207. package/src/plus/integrations/providers/azure/azure.ts +691 -0
  208. package/src/plus/integrations/providers/azure/models.ts +605 -0
  209. package/src/plus/integrations/providers/azureDevOps.ts +677 -0
  210. package/src/plus/integrations/providers/bitbucket/bitbucket.ts +774 -0
  211. package/src/plus/integrations/providers/bitbucket/models.ts +445 -0
  212. package/src/plus/integrations/providers/bitbucket-server/models.ts +252 -0
  213. package/src/plus/integrations/providers/bitbucket-server.ts +282 -0
  214. package/src/plus/integrations/providers/bitbucket.ts +350 -0
  215. package/src/plus/integrations/providers/github/github.ts +64 -0
  216. package/src/plus/integrations/providers/github/github.utils.ts +23 -0
  217. package/src/plus/integrations/providers/github/models.ts +29 -0
  218. package/src/plus/integrations/providers/github.ts +366 -0
  219. package/src/plus/integrations/providers/gitlab/gitlab.ts +1210 -0
  220. package/src/plus/integrations/providers/gitlab/gitlab.utils.ts +71 -0
  221. package/src/plus/integrations/providers/gitlab/models.ts +257 -0
  222. package/src/plus/integrations/providers/gitlab.ts +473 -0
  223. package/src/plus/integrations/providers/jira.ts +359 -0
  224. package/src/plus/integrations/providers/linear.ts +275 -0
  225. package/src/plus/integrations/providers/models.ts +1114 -0
  226. package/src/plus/integrations/providers/providersApi.ts +1126 -0
  227. package/src/plus/integrations/providers/utils.ts +359 -0
  228. package/src/plus/integrations/telemetry.ts +29 -0
  229. package/src/plus/integrations/utils/integration.utils.ts +138 -0
  230. package/src/utils/disposable.ts +15 -2
@@ -0,0 +1,383 @@
1
+ import type { Account } from '../../git/models/author.js';
2
+ import type { DefaultBranch } from '../../git/models/defaultBranch.js';
3
+ import type { Issue } from '../../git/models/issue.js';
4
+ import type { IssueOrPullRequest, IssueOrPullRequestType } from '../../git/models/issueOrPullRequest.js';
5
+ import type { PullRequest } from '../../git/models/pullRequest.js';
6
+ import type { GitRemote } from '../../git/models/remote.js';
7
+ import type { RepositoryMetadata } from '../../git/models/repositoryMetadata.js';
8
+ import type { ResourceDescriptor } from '../../git/models/resourceDescriptor.js';
9
+ import type { Event } from '../../utils/event.js';
10
+ import type { CacheController } from '../../utils/promiseCache.js';
11
+ import type { ConfiguredIntegrationService } from './authentication/configuredIntegrationService.js';
12
+ import type { IntegrationAuthenticationProvider } from './authentication/integrationAuthenticationProvider.js';
13
+ import type { IntegrationAuthenticationService } from './authentication/integrationAuthenticationService.js';
14
+ import type { IntegrationIds } from './constants.js';
15
+ import type { GitHostIntegration } from './models/gitHostIntegration.js';
16
+ import type { IntegrationBase } from './models/integration.js';
17
+ import type { Source } from './telemetry.js';
18
+
19
+ /**
20
+ * Context provided to {@link IntegrationService} at construction time.
21
+ *
22
+ * Replaces all extension-host coupling that integrations would otherwise reach
23
+ * for: storage, subscription, cloud connection, host-side authentication,
24
+ * configuration, commands, UI surfaces, etc. The package boundary at
25
+ * `@gitkraken/core-gitlens/plus/integrations` cannot import `vscode` or reach into the extension
26
+ * host directly — every cross-boundary concern is named here so the host can
27
+ * adapt its own services to satisfy it.
28
+ *
29
+ * Mirrors the {@link import('../../git/context.js').GitServiceContext} pattern.
30
+ */
31
+ export interface IntegrationServiceContext {
32
+ readonly storage: IntegrationStorageProvider;
33
+ readonly account: AccountProvider;
34
+ readonly config: ConfigProvider;
35
+ readonly http: HttpProvider;
36
+ readonly cache: IntegrationCacheProvider;
37
+ readonly repositories: RepositoriesProvider;
38
+ readonly hooks?: IntegrationServiceHooks;
39
+ }
40
+
41
+ /**
42
+ * The GitKraken account + the GK-cloud connect/manage flows. Unifies the former
43
+ * subscription/cloudConnection/authentication/uris ports: the host owns the GK-Dev OAuth round-trips
44
+ * end-to-end (URL shape, exchange token, redirect, callback, redeem), so the package stays out of the
45
+ * GK-cloud UI and only orchestrates (state, sync, hooks) around `connect`/`openManagement`.
46
+ */
47
+ export interface AccountProvider {
48
+ /**
49
+ * The signed-in GK account, or `undefined` when signed out. `createIfNeeded` triggers the host's
50
+ * sign-in/sign-up flow (folds the former `loginOrSignUp`/`isSignedIn`/`hasAccountSession`).
51
+ */
52
+ getAccount(options?: {
53
+ createIfNeeded?: boolean;
54
+ source?: Source;
55
+ }): Promise<{ id: string; name?: string; email?: string } | undefined>;
56
+ /** Fires when account/subscription state changes (login, logout, plan change). */
57
+ readonly onDidChange: Event<void>;
58
+ /**
59
+ * Fires on a host account check-in; `force` requests a force-refresh of cloud integration sessions
60
+ * (explicit re-validation: login, trial activation, manual validate).
61
+ */
62
+ readonly onDidCheckIn: Event<{ force?: boolean }>;
63
+ /** Fires when a host auth session changes (carries the changed provider id the package matches). */
64
+ readonly onDidChangeSessions: Event<AuthenticationSessionsChangeEvent>;
65
+ /**
66
+ * Whether the account is in a trial-or-paid state. Read by {@link IntegrationBase.access} to decide
67
+ * whether a connected integration's rich features are usable.
68
+ */
69
+ isTrialOrPaid(): Promise<boolean>;
70
+ /**
71
+ * Authenticated request against the GK cloud API (the connections/tokens endpoints used by
72
+ * `CloudIntegrationService`). Routes through the host's shared `ServerConnection` (circuit-breaker).
73
+ */
74
+ fetchGkApi(path: string, init?: RequestInit): Promise<Response>;
75
+ /**
76
+ * Run the GK-Dev connect flow for the given integrations: the host builds the connect URL (query,
77
+ * provider, exchange-token vs redirect), opens it, awaits its own OAuth callback, and signs in +
78
+ * connects in one round-trip. Returns `true` on success; the package syncs + fires hooks around it.
79
+ */
80
+ connect(options: { integrationIds?: IntegrationIds[]; source?: Source }): Promise<boolean>;
81
+ /**
82
+ * Open the GK-Dev integrations-management page (signing in first if needed) and resolve when the user
83
+ * returns to the window — `true` if they returned (so the package re-syncs), `false` otherwise.
84
+ */
85
+ openManagement(source?: Source): Promise<boolean>;
86
+ }
87
+
88
+ /** A cached value, possibly still resolving. Mirrors the host `CacheProvider`'s result shape. */
89
+ type CacheResult<T> = Promise<T | undefined> | T | undefined;
90
+ /** Produces the value (and optional expiry) to cache on a miss; the controller allows invalidation. */
91
+ type Cacheable<T> = (cacheable: CacheController) => { value: CacheResult<T>; expiresAt?: number };
92
+ /** Cache expiry controls. */
93
+ interface CacheExpiryOptions {
94
+ expiryOverride?: boolean | number;
95
+ expireOnError?: boolean;
96
+ }
97
+
98
+ /**
99
+ * Cross-call cache for expensive provider lookups. Wraps the host's cache
100
+ * service, which deduplicates concurrent loads for the same logical key.
101
+ *
102
+ * Method names + shapes mirror the host's `CacheProvider` so the package routes
103
+ * every cache call through this provider without adapting call sites — and the
104
+ * host adapter can assign its real `CacheProvider` directly (no cast).
105
+ */
106
+ export interface IntegrationCacheProvider {
107
+ getRepositoryMetadata(
108
+ repo: ResourceDescriptor,
109
+ integration: GitHostIntegration | undefined,
110
+ cacheable: Cacheable<RepositoryMetadata>,
111
+ options?: CacheExpiryOptions,
112
+ ): CacheResult<RepositoryMetadata>;
113
+ getRepositoryDefaultBranch(
114
+ repo: ResourceDescriptor,
115
+ integration: GitHostIntegration | undefined,
116
+ cacheable: Cacheable<DefaultBranch>,
117
+ options?: CacheExpiryOptions,
118
+ ): CacheResult<DefaultBranch>;
119
+ getPullRequestForSha(
120
+ sha: string,
121
+ repo: ResourceDescriptor,
122
+ integration: GitHostIntegration | undefined,
123
+ cacheable: Cacheable<PullRequest>,
124
+ options?: CacheExpiryOptions,
125
+ ): CacheResult<PullRequest>;
126
+ getPullRequestForBranch(
127
+ branch: string,
128
+ repo: ResourceDescriptor,
129
+ integration: GitHostIntegration | undefined,
130
+ cacheable: Cacheable<PullRequest>,
131
+ options?: CacheExpiryOptions,
132
+ ): CacheResult<PullRequest>;
133
+ getPullRequest(
134
+ id: string,
135
+ resource: ResourceDescriptor,
136
+ integration: IntegrationBase | undefined,
137
+ cacheable: Cacheable<PullRequest>,
138
+ options?: CacheExpiryOptions,
139
+ ): CacheResult<PullRequest>;
140
+ getIssueOrPullRequest(
141
+ id: string,
142
+ type: IssueOrPullRequestType | undefined,
143
+ resource: ResourceDescriptor,
144
+ integration: IntegrationBase | undefined,
145
+ cacheable: Cacheable<IssueOrPullRequest>,
146
+ options?: CacheExpiryOptions,
147
+ ): CacheResult<IssueOrPullRequest>;
148
+ getIssue(
149
+ id: string,
150
+ resource: ResourceDescriptor,
151
+ integration: IntegrationBase | undefined,
152
+ cacheable: Cacheable<Issue>,
153
+ options?: CacheExpiryOptions,
154
+ ): CacheResult<Issue>;
155
+ getCurrentAccount(
156
+ integration: IntegrationBase,
157
+ cacheable: Cacheable<Account>,
158
+ options?: CacheExpiryOptions,
159
+ ): CacheResult<Account>;
160
+ }
161
+
162
+ /**
163
+ * The remotes across all currently-open repositories. The package only ever needs the *remotes* (to map
164
+ * them to integrations) — never the repositories themselves — so the host flattens to a remote list
165
+ * rather than leaking a repository shape across the boundary. Used for "across all open repos" queries:
166
+ * issue aggregation by remote ({@link IntegrationService.getMyIssues}) and bitbucket's reviewing-PRs search.
167
+ */
168
+ export interface RepositoriesProvider {
169
+ getOpenRemotes(): Promise<readonly GitRemote[]>;
170
+ }
171
+
172
+ /**
173
+ * HTTP primitives the package uses to call out to provider APIs. Wraps the
174
+ * host's `@env/fetch` (which differs between Node and browser builds) so the
175
+ * package itself stays environment-agnostic.
176
+ */
177
+ export interface HttpProvider {
178
+ /** Whether the package is running in a webworker/browser environment. */
179
+ readonly isWeb: boolean;
180
+ /** Pre-assembled User-Agent string for provider API requests (host builds it from its env facts). */
181
+ readonly userAgent: string;
182
+ /** Host-supplied fetch implementation. */
183
+ fetch(input: string | URL, init?: RequestInit): Promise<Response>;
184
+ /**
185
+ * Wrap a fetch in the host's "ignore SSL errors" toggle. On Node, this
186
+ * disables TLS verification while the wrapped fetch is in flight; on the
187
+ * browser, it's a no-op.
188
+ */
189
+ wrapForForcedInsecureSSL<T>(ignoreSSLErrors: boolean | 'force', fn: () => Promise<T> | PromiseLike<T>): Promise<T>;
190
+ }
191
+
192
+ /**
193
+ * Persists integration token/session/configured-integration state.
194
+ * Wraps the host's `Container.storage` (global + workspace + secret stores).
195
+ *
196
+ * Two non-secret namespaces:
197
+ * - **Global** (`get`/`store`/`delete`/`deleteWithPrefix`) — values shared
198
+ * across all workspaces (e.g., the `integrations:configured` descriptor
199
+ * map, per-account caches keyed by access token).
200
+ * - **Workspace** (`getWorkspace`/`storeWorkspace`/`deleteWorkspace`) —
201
+ * values scoped to the active workspace (e.g., `connected:<id>` flags).
202
+ *
203
+ * Plus a **Secret** namespace (`getSecret`/`storeSecret`/`deleteSecret`)
204
+ * for OAuth tokens and other credentials.
205
+ *
206
+ * Method names mirror the host's `Storage` API so the package can route
207
+ * every storage access through this provider without renaming call sites.
208
+ */
209
+ export interface IntegrationStorageProvider {
210
+ /** Read a global (cross-workspace) value (non-secret). */
211
+ get<T = any>(key: string): T | undefined;
212
+ /** Write a global (cross-workspace) value (non-secret). */
213
+ store<T = any>(key: string, value: T): Promise<void>;
214
+ /** Delete a global value. */
215
+ delete(key: string): Promise<void>;
216
+ /** Delete every global key with the given prefix. */
217
+ deleteWithPrefix(prefix: string): Promise<void>;
218
+ /** Read a workspace-scoped value (non-secret). */
219
+ getWorkspace<T = any>(key: string): T | undefined;
220
+ /** Write a workspace-scoped value (non-secret). */
221
+ storeWorkspace<T = any>(key: string, value: T): Promise<void>;
222
+ /** Delete a workspace-scoped value (non-secret). */
223
+ deleteWorkspace(key: string): Promise<void>;
224
+ /** Read a secret (e.g., access token). */
225
+ getSecret(key: string): Promise<string | undefined>;
226
+ /** Store a secret. */
227
+ storeSecret(key: string, value: string): Promise<void>;
228
+ /** Delete a secret. */
229
+ deleteSecret(key: string): Promise<void>;
230
+ }
231
+
232
+ export interface AuthenticationSessionsChangeEvent {
233
+ readonly provider: { readonly id: string };
234
+ }
235
+
236
+ /**
237
+ * Per-remote-host configuration entry (subset of the host's `RemotesConfig`).
238
+ * Used by `IntegrationService.ignoreSSLErrors` to look up self-managed remote
239
+ * settings.
240
+ */
241
+ export interface IntegrationsRemoteConfig {
242
+ readonly type: string;
243
+ readonly domain: string;
244
+ readonly ignoreSSLErrors?: boolean | 'force';
245
+ }
246
+
247
+ /**
248
+ * Snapshot of integration-relevant config values + reactive change detection.
249
+ *
250
+ * Only the keys integrations actually read are surfaced; everything else is
251
+ * the host's concern. Host adapter wraps the `system/-webview/configuration`
252
+ * helper to satisfy this.
253
+ */
254
+ export interface ConfigProvider {
255
+ /** `integrations.enabled`. Optional — omit (or omit a `false` return) and integrations are enabled. */
256
+ isIntegrationsEnabled?(): boolean;
257
+ /**
258
+ * `launchpad.*` knobs surfaced to the GitHub provider.
259
+ */
260
+ getLaunchpadOptions(): {
261
+ queryLimit?: number;
262
+ ignoredRepositories?: readonly string[];
263
+ includedOrganizations?: readonly string[];
264
+ ignoredOrganizations?: readonly string[];
265
+ };
266
+ /** Per-remote-host configurations from `remotes`. */
267
+ getRemoteConfigs(): readonly IntegrationsRemoteConfig[];
268
+ /** Fires when any integration-relevant config changes. */
269
+ readonly onDidChange: Event<ConfigChangeEvent>;
270
+ }
271
+
272
+ /** Typed change descriptor returned by {@link ConfigProvider.onDidChange}. */
273
+ export interface ConfigChangeEvent {
274
+ /** Whether `remotes` configuration changed. */
275
+ readonly remotes: boolean;
276
+ /** Whether `integrations.enabled` changed. */
277
+ readonly integrationsEnabled: boolean;
278
+ /** Whether one of the `launchpad.*` keys changed. */
279
+ readonly launchpad: boolean;
280
+ /** Whether `http.proxy` or `http.proxyStrictSSL` (VS Code core) changed. */
281
+ readonly httpProxy: boolean;
282
+ }
283
+
284
+ /**
285
+ * Outbound hooks: the package raises domain events the host wants to observe
286
+ * and exposes host-owned composition hooks (e.g., `createAuthenticationProvider`).
287
+ *
288
+ * Hooks are optional; the package omits the call when unset. They follow the
289
+ * pattern used by `@gitkraken/core-gitlens/plus/agents` (`AgentProviderCallbacks`) and the
290
+ * existing `GitServiceHooks` — the package surfaces named events; the host
291
+ * decides what to do (send telemetry, log, update UI, etc.).
292
+ *
293
+ * Replaces the direct `Container.telemetry.sendEvent` calls scattered through
294
+ * integration source today. Each hook below is named after the domain event,
295
+ * not its current telemetry event name; the host adapter forwards each one to
296
+ * the corresponding `telemetry.sendEvent('cloudIntegrations/...')` call to
297
+ * preserve existing analytics.
298
+ */
299
+ export interface IntegrationServiceHooks {
300
+ /**
301
+ * Ask the host to confirm reauthentication after an integration auth/permission failure. The host
302
+ * owns the prompt (and its "Reauthenticate" affordance) and resolves to the user's choice; the
303
+ * package performs the actual reauth when this resolves truthy. Omit to never prompt.
304
+ */
305
+ onReauthenticationRequired?(message: string): Promise<boolean | undefined>;
306
+
307
+ /**
308
+ * Confirm disabling a connected integration. The host renders the dialog (offering a "sign out"
309
+ * choice when `offerSignOut`); resolves to the user's decision, or `undefined` to cancel. Omit to
310
+ * make interactive `disconnect()` a no-op (callers should pass `silent`/`currentSessionOnly` then).
311
+ */
312
+ onConfirmDisconnect?(e: {
313
+ integrationName: string;
314
+ offerSignOut: boolean;
315
+ }): Promise<{ signOut: boolean } | undefined>;
316
+
317
+ /**
318
+ * Optional consumer override: construct a custom authentication provider for `id` (e.g. a manual-token
319
+ * provider via {@link createManualTokenAuthProvider}). Return `undefined` to defer to the package's own
320
+ * cloud-OAuth provider. GitLens omits this — the package builds its cloud providers internally; an
321
+ * external consumer can plug in any auth strategy here.
322
+ */
323
+ createAuthenticationProvider?(args: {
324
+ id: IntegrationIds;
325
+ auth: IntegrationAuthenticationService;
326
+ configured: ConfiguredIntegrationService;
327
+ }): Promise<IntegrationAuthenticationProvider | undefined>;
328
+
329
+ /**
330
+ * Outbound behavioral events, nested by domain — mirroring `@gitkraken/core-gitlens/git`'s `GitServiceHooks`. The
331
+ * package raises typed domain events; the host decides what to do (GitLens maps each to its telemetry
332
+ * schema, but a consumer could log or ignore them — they're behavioral, not telemetry-specific).
333
+ * Optional throughout — omit to opt out entirely (no stub functions needed).
334
+ */
335
+ connection?: {
336
+ /** A connect flow was initiated. */
337
+ onStarted?(e: { integrationIds: IntegrationIds[] | undefined }, source: Source | undefined): void;
338
+ /** A connect flow finished syncing. */
339
+ onCompleted?(
340
+ e: { integrationIds: IntegrationIds[] | undefined; connectedIntegrationIds: IntegrationIds[] | undefined },
341
+ source: Source | undefined,
342
+ ): void;
343
+ /** The user opened the integrations management surface. */
344
+ onManaged?(source: Source | undefined): void;
345
+ /** A hosting/remote/issue integration's connection state changed. */
346
+ onStateChanged?(e: {
347
+ id: IntegrationIds;
348
+ key: string;
349
+ connected: boolean;
350
+ kind: 'hosting' | 'remote' | 'issue';
351
+ }): void;
352
+ /** The set of connected integrations changed (e.g. for connected-count attributes). */
353
+ onConnectedChanged?(e: { integrationIds: IntegrationIds[] }): void;
354
+ /** Fetching the set of connected providers failed. */
355
+ onConnectionsFetchFailed?(e: { code: number | undefined }): void;
356
+ /** Fetching/refreshing a single provider's token failed. */
357
+ onConnectionFetchFailed?(e: { id: IntegrationIds; code: number | undefined; refreshing: boolean }): void;
358
+ /** Disconnecting a provider's token failed. */
359
+ onDisconnectFailed?(e: { id: IntegrationIds; code: number | undefined }): void;
360
+ };
361
+ /** Outbound session events (behavioral; the host maps to telemetry). */
362
+ session?: {
363
+ /** A session refresh was skipped (reported once per reason). */
364
+ onRefreshSkipped?(e: {
365
+ id: IntegrationIds;
366
+ reason: 'skip-non-cloud' | 'missing-expiry';
367
+ cloud: boolean | undefined;
368
+ }): void;
369
+ };
370
+ /** Outbound user-facing notifications (fire-and-forget). The host renders them; a consumer may log/ignore. */
371
+ ui?: {
372
+ /** A non-fatal error to surface. */
373
+ onError?(message: string): void;
374
+ /** The integration's API returned a 500-level error. */
375
+ onRequestFailed?(message: string): void;
376
+ /** The integration's API request timed out. */
377
+ onRequestTimedOut?(integrationName: string): void;
378
+ /** An integration was disconnected after too many consecutive failed requests. */
379
+ onDisconnectedAfterTooManyFailures?(integrationName: string): void;
380
+ /** Bitbucket's "Pull Requests for Commit" app isn't installed; `revLink` opens the install page. */
381
+ onBitbucketCommitLinksAppMissing?(revLink: string): void;
382
+ };
383
+ }
@@ -0,0 +1,35 @@
1
+ export type { AuthTokenInfo } from '../../git/errors.js';
2
+ export {
3
+ AuthenticationError,
4
+ AuthenticationErrorReason,
5
+ RequestClientError,
6
+ RequestNotFoundError,
7
+ RequestRateLimitError,
8
+ } from '../../git/errors.js';
9
+
10
+ /**
11
+ * Thrown by integration provider HTTP clients when an upstream request fails.
12
+ */
13
+ export class ProviderFetchError extends Error {
14
+ get status(): number {
15
+ return this.response.status;
16
+ }
17
+
18
+ get statusText(): string {
19
+ return this.response.statusText;
20
+ }
21
+
22
+ constructor(
23
+ provider: string,
24
+ public readonly response: Response,
25
+ errors?: { message: string }[],
26
+ ) {
27
+ super(
28
+ `${provider} request failed: ${!response.ok ? `(${response.status}) ${response.statusText}. ` : ''}${
29
+ errors?.length ? errors[0].message : ''
30
+ }`,
31
+ );
32
+
33
+ Error.captureStackTrace?.(this, new.target);
34
+ }
35
+ }
@@ -0,0 +1,119 @@
1
+ // Public facade for `@gitkraken/core-gitlens/plus/integrations`.
2
+ //
3
+ // External consumers should import from this entry point only, not from the
4
+ // package's internal subpaths. The internal classes (IntegrationService,
5
+ // IntegrationAuthenticationService, etc.) are not part of the public API and
6
+ // may be refactored without semver bumps.
7
+
8
+ import { CloudIntegrationService } from './authentication/cloudIntegrationService.js';
9
+ import { ConfiguredIntegrationService } from './authentication/configuredIntegrationService.js';
10
+ import { IntegrationAuthenticationService } from './authentication/integrationAuthenticationService.js';
11
+ import type { IntegrationServiceContext } from './context.js';
12
+ import { IntegrationService } from './integrationService.js';
13
+
14
+ /**
15
+ * The public manager — what consumers get back from
16
+ * {@link createIntegrationManager}. Identical shape to {@link IntegrationService}
17
+ * for now (we may narrow this surface in a future major).
18
+ */
19
+ export type IntegrationManager = IntegrationService;
20
+
21
+ /**
22
+ * Construct an `@gitkraken/core-gitlens/plus/integrations` manager bound to the supplied runtime.
23
+ *
24
+ * The runtime is the **single** cross-boundary contract — anything the
25
+ * package needs (HTTP, storage, cache, auth, subscription, telemetry, UI,
26
+ * configuration, environment) flows through it. The package never imports
27
+ * `vscode`, `Container`, or any consumer-internal types.
28
+ *
29
+ * The returned manager owns its internal services; dispose it (or its
30
+ * containing scope) to release every cached integration plus the runtime's
31
+ * own VS Code subscriptions.
32
+ */
33
+ export function createIntegrationManager(ctx: IntegrationServiceContext): IntegrationManager {
34
+ const configured = new ConfiguredIntegrationService(ctx);
35
+ // The cloud token-exchange client is a pure package service (needs only `ctx`); construct it here
36
+ // rather than round-tripping through a host hook.
37
+ const cloud = new CloudIntegrationService(ctx);
38
+ // Cloud auth providers need to (re)initiate the connect flow that lives on the service, but the
39
+ // service is constructed after the auth service (it depends on it). Break the cycle here at the
40
+ // composition root with a lazy, readonly accessor — preserving constructor injection while
41
+ // keeping the flow in-package (no host round-trip).
42
+ let service: IntegrationService;
43
+ const auth = new IntegrationAuthenticationService(configured, ctx, () => service, cloud);
44
+ service = new IntegrationService(auth, configured, ctx);
45
+ // One-time cleanup of storage left behind by integration ids retired in the cloud-only refactor (the
46
+ // local self-managed `github-enterprise`/`gitlab-self-hosted` providers). Best-effort and guarded so it
47
+ // runs once; a no-op for consumers that never stored those ids.
48
+ void purgeRetiredIntegrationStorage(ctx, configured);
49
+ return service;
50
+ }
51
+
52
+ const retiredIntegrationsStorageKey = 'integrations:migrated:cloudOnly';
53
+ async function purgeRetiredIntegrationStorage(
54
+ ctx: IntegrationServiceContext,
55
+ configured: ConfiguredIntegrationService,
56
+ ): Promise<void> {
57
+ if (ctx.storage.get<boolean>(retiredIntegrationsStorageKey)) return;
58
+
59
+ try {
60
+ await configured.purgeStoredConfiguration(['github-enterprise', 'gitlab-self-hosted']);
61
+ // Only mark the migration done once the purge fully succeeds. A partial/failed purge stays
62
+ // un-flagged so it retries (idempotently) on the next startup, rather than orphaning the
63
+ // retired-id config/secrets forever.
64
+ await ctx.storage.store(retiredIntegrationsStorageKey, true);
65
+ } catch {
66
+ // Best-effort cleanup: swallow so the failure doesn't reject the fire-and-forget caller; the
67
+ // unset flag guarantees a retry next startup.
68
+ }
69
+ }
70
+
71
+ // Re-exports for the public API surface.
72
+ export type {
73
+ AccountProvider,
74
+ AuthenticationSessionsChangeEvent,
75
+ IntegrationCacheProvider,
76
+ ConfigChangeEvent,
77
+ ConfigProvider,
78
+ RepositoriesProvider,
79
+ HttpProvider,
80
+ IntegrationServiceContext,
81
+ IntegrationServiceHooks,
82
+ IntegrationStorageProvider,
83
+ } from './context.js';
84
+ export type { ApiClients } from './providers/apiClients.js';
85
+ export type { Source } from './telemetry.js';
86
+ export type { IntegrationIds, SupportedCloudIntegrationIds } from './constants.js';
87
+ export type { ConnectionStateChangeEvent, IntegrationConnectionChangeEvent } from './integrationService.js';
88
+ export type { ConfiguredIntegrationsChangeEvent } from './authentication/configuredIntegrationService.js';
89
+
90
+ // Authentication contract — what `IntegrationServiceHooks.createAuthenticationProvider`
91
+ // implementers return. Consumers can plug in any auth strategy (manual token,
92
+ // OAuth, host-managed) by returning an object implementing this interface from
93
+ // the hook.
94
+ export type {
95
+ IntegrationAuthenticationProvider,
96
+ IntegrationAuthenticationProviderDescriptor,
97
+ IntegrationAuthenticationSessionDescriptor,
98
+ } from './authentication/integrationAuthenticationProvider.js';
99
+ export type {
100
+ AuthenticationSessionLike,
101
+ CloudIntegrationAuthType,
102
+ ProviderAuthenticationSession,
103
+ } from './authentication/models.js';
104
+
105
+ // Convenience: wrap a static access token (env var, CLI flag, secret manager)
106
+ // as an `IntegrationAuthenticationProvider`. For OAuth/refresh flows, implement
107
+ // the interface directly — this helper is for non-interactive consumers only.
108
+ export {
109
+ createManualTokenAuthProvider,
110
+ type ManualTokenAuthProviderOptions,
111
+ } from './authentication/manualTokenProvider.js';
112
+
113
+ export {
114
+ GitCloudHostIntegrationId,
115
+ GitSelfManagedHostIntegrationId,
116
+ IssuesCloudHostIntegrationId,
117
+ isIntegrationId,
118
+ isSupportedCloudIntegrationId,
119
+ } from './constants.js';