@cesar-richard/git-connector-sdk 1.32.0 → 1.33.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 CHANGED
@@ -154,6 +154,86 @@ for (const e of data.events) {
154
154
 
155
155
  Available on every commit event regardless of provider or ingestion path. `event.author` is always equal to `event.authorResolved?.login`.
156
156
 
157
+ ### User resolution on work-items (`assigneesResolved`, `authorResolved`, `reviewerResolved`)
158
+
159
+ Beyond commit events, `/v1/work-items` exposes resolved user identities on
160
+ work-item assignees, linked-activity authors, and reviewers. Each is a
161
+ `ResolvedUser` shape:
162
+
163
+ ```ts
164
+ type ResolvedUser = {
165
+ id: string; // "gl:<user_id>" or "gh:<login>" — stable across login renames
166
+ login: string;
167
+ name: string | null;
168
+ email: string | null;
169
+ };
170
+ ```
171
+
172
+ The `id` is stable: two references to the same GitLab user retain the same
173
+ `gl:<user_id>` even after the user's username changes (a common pattern in
174
+ self-hosted GitLab where matricule-based logins get rewritten to friendly
175
+ names later). GitHub usernames don't typically change in a way that affects
176
+ this, so `id` is `gh:<login>` for GitHub users.
177
+
178
+ ```ts
179
+ const { data } = await client.GET("/v1/work-items");
180
+ for (const wi of data.items) {
181
+ for (const a of wi.assigneesResolved ?? []) {
182
+ console.log(`${wi.title} assigned to ${a.name ?? a.login} (id=${a.id})`);
183
+ }
184
+ for (const pr of wi.linkedActivities) {
185
+ if (pr.authorResolved) {
186
+ console.log(`PR ${pr.url} by ${pr.authorResolved.name ?? pr.authorResolved.login}`);
187
+ }
188
+ for (const rev of pr.reviews.entries) {
189
+ console.log(` review by ${rev.reviewerResolved?.name ?? rev.reviewer}`);
190
+ }
191
+ }
192
+ }
193
+ ```
194
+
195
+ GitLab resolution uses a 90-day cache (configurable via `GITLAB_USER_CACHE_TTL_DAYS`).
196
+
197
+ ### Issue ↔ PR/MR link detection patterns
198
+
199
+ `WorkItem.linkedActivities` is populated by scanning PR/MR bodies, commit
200
+ messages, notes, AND issue comments for references to PR/MR numbers or URLs.
201
+ The recognized patterns are:
202
+
203
+ **Canonical (in PR/MR body / commits / notes — forward direction):**
204
+
205
+ - `Fixes #1234`, `Fix #1234`, `Closes #1234`, `Close #1234`, `Resolves #1234`,
206
+ `Resolve #1234` (English short refs).
207
+ - `https://github.com/<owner>/<repo>/issues/<n>` or `https://<gitlab>/.../-/issues/<n>`
208
+ (full URLs).
209
+ - `<owner>/<repo>#<n>` (cross-repo GitHub).
210
+ - `<alias>#<n>` and `<alias>!<n>` (project-alias cross-repo).
211
+ - Short refs `#<n>` and `!<n>` (resolved against the active provider/project).
212
+
213
+ **Issue-comment reverse direction (`hint_source="issue_comment"`):**
214
+
215
+ The above PR/MR URLs and short refs are all recognized in **issue comments**
216
+ as evidence that the cited PR/MR is linked to the issue.
217
+
218
+ Additionally, the following **explicit phrase prefixes** are recognized,
219
+ case-insensitively, to catch informal "this issue was delivered" comments:
220
+
221
+ | Phrase | Example | Behavior |
222
+ |---|---|---|
223
+ | `Fixed by …`, `Fixed in …` | `Fixed by 1214`, `Fixed by https://…/pull/1214` | Treat the cited ref as a linked PR/MR |
224
+ | `Fixes by …`, `Fix by …` | `Fix by #99` | Same |
225
+ | `Resolved by …`, `Resolves by …`, `Resolve by …` | `Resolved by 42` | Same |
226
+ | `Closed by …`, `Closes by …`, `Close by …` | `Closed by !99` | Same |
227
+ | FR: `Corrigé par …`, `Corrigée par …`, `Corrige par …` | `Corrigé par 42` | Same |
228
+ | FR: `Résolu par …`, `Resolu par …` | `Résolu par !99` | Same |
229
+ | FR: `Fermé par …`, `Ferme par …` | `Fermé par #1214` | Same |
230
+ | FR: `… dans <n>` variant | `Corrigé dans 42` | Same |
231
+
232
+ The phrase prefix lets the SDK detect refs even when the number is **bare**
233
+ (no `#` or `!` prefix), e.g. `Fixed by 1214` instead of `Fixed by #1214`.
234
+
235
+ Code blocks (fenced ```` ``` ```` and inline `` ` ``) are stripped before scanning.
236
+
157
237
  ### PR review status (`reviewStatus`)
158
238
 
159
239
  Each `LinkedActivity` carries an optional `reviewStatus` field with 8 possible
package/dist/schema.d.ts CHANGED
@@ -214,6 +214,12 @@ export interface components {
214
214
  hasConflicts: boolean;
215
215
  awaitingReview: boolean;
216
216
  author: string | null;
217
+ authorResolved?: {
218
+ id: string;
219
+ login: string;
220
+ name: string | null;
221
+ email: string | null;
222
+ } | null;
217
223
  updatedAt: string;
218
224
  mergedAt: string | null;
219
225
  reviewRequestedAt: string | null;
@@ -240,6 +246,12 @@ export interface components {
240
246
  entries: {
241
247
  state: "approved" | "changes_requested" | "commented" | "dismissed";
242
248
  reviewer: string;
249
+ reviewerResolved?: {
250
+ id: string;
251
+ login: string;
252
+ name: string | null;
253
+ email: string | null;
254
+ };
243
255
  submittedAt: string;
244
256
  url: string | null;
245
257
  }[];
@@ -257,9 +269,21 @@ export interface components {
257
269
  reviewStatus?: "draft" | "open-no-review" | "open-awaiting-my-review" | "open-awaiting-other-review" | "open-changes-requested" | "open-approved" | "merged" | "closed";
258
270
  };
259
271
  Provider: "github" | "gitlab";
272
+ ResolvedUser: {
273
+ id: string;
274
+ login: string;
275
+ name: string | null;
276
+ email: string | null;
277
+ };
260
278
  Review: {
261
279
  state: "approved" | "changes_requested" | "commented" | "dismissed";
262
280
  reviewer: string;
281
+ reviewerResolved?: {
282
+ id: string;
283
+ login: string;
284
+ name: string | null;
285
+ email: string | null;
286
+ };
263
287
  submittedAt: string;
264
288
  url: string | null;
265
289
  };
@@ -272,6 +296,12 @@ export interface components {
272
296
  entries: {
273
297
  state: "approved" | "changes_requested" | "commented" | "dismissed";
274
298
  reviewer: string;
299
+ reviewerResolved?: {
300
+ id: string;
301
+ login: string;
302
+ name: string | null;
303
+ email: string | null;
304
+ };
275
305
  submittedAt: string;
276
306
  url: string | null;
277
307
  }[];
@@ -329,6 +359,12 @@ export interface components {
329
359
  } | null;
330
360
  milestone: string | null;
331
361
  assignees: string[];
362
+ assigneesResolved?: {
363
+ id: string;
364
+ login: string;
365
+ name: string | null;
366
+ email: string | null;
367
+ }[];
332
368
  labels: {
333
369
  name: string;
334
370
  color: string | null;
@@ -344,6 +380,12 @@ export interface components {
344
380
  hasConflicts: boolean;
345
381
  awaitingReview: boolean;
346
382
  author: string | null;
383
+ authorResolved?: {
384
+ id: string;
385
+ login: string;
386
+ name: string | null;
387
+ email: string | null;
388
+ } | null;
347
389
  updatedAt: string;
348
390
  mergedAt: string | null;
349
391
  reviewRequestedAt: string | null;
@@ -370,6 +412,12 @@ export interface components {
370
412
  entries: {
371
413
  state: "approved" | "changes_requested" | "commented" | "dismissed";
372
414
  reviewer: string;
415
+ reviewerResolved?: {
416
+ id: string;
417
+ login: string;
418
+ name: string | null;
419
+ email: string | null;
420
+ };
373
421
  submittedAt: string;
374
422
  url: string | null;
375
423
  }[];
@@ -428,6 +476,12 @@ export interface components {
428
476
  } | null;
429
477
  milestone: string | null;
430
478
  assignees: string[];
479
+ assigneesResolved?: {
480
+ id: string;
481
+ login: string;
482
+ name: string | null;
483
+ email: string | null;
484
+ }[];
431
485
  labels: {
432
486
  name: string;
433
487
  color: string | null;
@@ -443,6 +497,12 @@ export interface components {
443
497
  hasConflicts: boolean;
444
498
  awaitingReview: boolean;
445
499
  author: string | null;
500
+ authorResolved?: {
501
+ id: string;
502
+ login: string;
503
+ name: string | null;
504
+ email: string | null;
505
+ } | null;
446
506
  updatedAt: string;
447
507
  mergedAt: string | null;
448
508
  reviewRequestedAt: string | null;
@@ -469,6 +529,12 @@ export interface components {
469
529
  entries: {
470
530
  state: "approved" | "changes_requested" | "commented" | "dismissed";
471
531
  reviewer: string;
532
+ reviewerResolved?: {
533
+ id: string;
534
+ login: string;
535
+ name: string | null;
536
+ email: string | null;
537
+ };
472
538
  submittedAt: string;
473
539
  url: string | null;
474
540
  }[];
@@ -576,6 +642,12 @@ export interface operations {
576
642
  } | null;
577
643
  milestone: string | null;
578
644
  assignees: string[];
645
+ assigneesResolved?: {
646
+ id: string;
647
+ login: string;
648
+ name: string | null;
649
+ email: string | null;
650
+ }[];
579
651
  labels: {
580
652
  name: string;
581
653
  color: string | null;
@@ -591,6 +663,12 @@ export interface operations {
591
663
  hasConflicts: boolean;
592
664
  awaitingReview: boolean;
593
665
  author: string | null;
666
+ authorResolved?: {
667
+ id: string;
668
+ login: string;
669
+ name: string | null;
670
+ email: string | null;
671
+ } | null;
594
672
  updatedAt: string;
595
673
  mergedAt: string | null;
596
674
  reviewRequestedAt: string | null;
@@ -617,6 +695,12 @@ export interface operations {
617
695
  entries: {
618
696
  state: "approved" | "changes_requested" | "commented" | "dismissed";
619
697
  reviewer: string;
698
+ reviewerResolved?: {
699
+ id: string;
700
+ login: string;
701
+ name: string | null;
702
+ email: string | null;
703
+ };
620
704
  submittedAt: string;
621
705
  url: string | null;
622
706
  }[];
@@ -679,6 +763,12 @@ export interface operations {
679
763
  } | null;
680
764
  milestone: string | null;
681
765
  assignees: string[];
766
+ assigneesResolved?: {
767
+ id: string;
768
+ login: string;
769
+ name: string | null;
770
+ email: string | null;
771
+ }[];
682
772
  labels: {
683
773
  name: string;
684
774
  color: string | null;
@@ -694,6 +784,12 @@ export interface operations {
694
784
  hasConflicts: boolean;
695
785
  awaitingReview: boolean;
696
786
  author: string | null;
787
+ authorResolved?: {
788
+ id: string;
789
+ login: string;
790
+ name: string | null;
791
+ email: string | null;
792
+ } | null;
697
793
  updatedAt: string;
698
794
  mergedAt: string | null;
699
795
  reviewRequestedAt: string | null;
@@ -720,6 +816,12 @@ export interface operations {
720
816
  entries: {
721
817
  state: "approved" | "changes_requested" | "commented" | "dismissed";
722
818
  reviewer: string;
819
+ reviewerResolved?: {
820
+ id: string;
821
+ login: string;
822
+ name: string | null;
823
+ email: string | null;
824
+ };
723
825
  submittedAt: string;
724
826
  url: string | null;
725
827
  }[];
@@ -782,6 +884,12 @@ export interface operations {
782
884
  } | null;
783
885
  milestone: string | null;
784
886
  assignees: string[];
887
+ assigneesResolved?: {
888
+ id: string;
889
+ login: string;
890
+ name: string | null;
891
+ email: string | null;
892
+ }[];
785
893
  labels: {
786
894
  name: string;
787
895
  color: string | null;
@@ -797,6 +905,12 @@ export interface operations {
797
905
  hasConflicts: boolean;
798
906
  awaitingReview: boolean;
799
907
  author: string | null;
908
+ authorResolved?: {
909
+ id: string;
910
+ login: string;
911
+ name: string | null;
912
+ email: string | null;
913
+ } | null;
800
914
  updatedAt: string;
801
915
  mergedAt: string | null;
802
916
  reviewRequestedAt: string | null;
@@ -823,6 +937,12 @@ export interface operations {
823
937
  entries: {
824
938
  state: "approved" | "changes_requested" | "commented" | "dismissed";
825
939
  reviewer: string;
940
+ reviewerResolved?: {
941
+ id: string;
942
+ login: string;
943
+ name: string | null;
944
+ email: string | null;
945
+ };
826
946
  submittedAt: string;
827
947
  url: string | null;
828
948
  }[];
@@ -909,6 +1029,12 @@ export interface operations {
909
1029
  } | null;
910
1030
  milestone: string | null;
911
1031
  assignees: string[];
1032
+ assigneesResolved?: {
1033
+ id: string;
1034
+ login: string;
1035
+ name: string | null;
1036
+ email: string | null;
1037
+ }[];
912
1038
  labels: {
913
1039
  name: string;
914
1040
  color: string | null;
@@ -924,6 +1050,12 @@ export interface operations {
924
1050
  hasConflicts: boolean;
925
1051
  awaitingReview: boolean;
926
1052
  author: string | null;
1053
+ authorResolved?: {
1054
+ id: string;
1055
+ login: string;
1056
+ name: string | null;
1057
+ email: string | null;
1058
+ } | null;
927
1059
  updatedAt: string;
928
1060
  mergedAt: string | null;
929
1061
  reviewRequestedAt: string | null;
@@ -950,6 +1082,12 @@ export interface operations {
950
1082
  entries: {
951
1083
  state: "approved" | "changes_requested" | "commented" | "dismissed";
952
1084
  reviewer: string;
1085
+ reviewerResolved?: {
1086
+ id: string;
1087
+ login: string;
1088
+ name: string | null;
1089
+ email: string | null;
1090
+ };
953
1091
  submittedAt: string;
954
1092
  url: string | null;
955
1093
  }[];
@@ -1007,6 +1145,12 @@ export interface operations {
1007
1145
  } | null;
1008
1146
  milestone: string | null;
1009
1147
  assignees: string[];
1148
+ assigneesResolved?: {
1149
+ id: string;
1150
+ login: string;
1151
+ name: string | null;
1152
+ email: string | null;
1153
+ }[];
1010
1154
  labels: {
1011
1155
  name: string;
1012
1156
  color: string | null;
@@ -1022,6 +1166,12 @@ export interface operations {
1022
1166
  hasConflicts: boolean;
1023
1167
  awaitingReview: boolean;
1024
1168
  author: string | null;
1169
+ authorResolved?: {
1170
+ id: string;
1171
+ login: string;
1172
+ name: string | null;
1173
+ email: string | null;
1174
+ } | null;
1025
1175
  updatedAt: string;
1026
1176
  mergedAt: string | null;
1027
1177
  reviewRequestedAt: string | null;
@@ -1048,6 +1198,12 @@ export interface operations {
1048
1198
  entries: {
1049
1199
  state: "approved" | "changes_requested" | "commented" | "dismissed";
1050
1200
  reviewer: string;
1201
+ reviewerResolved?: {
1202
+ id: string;
1203
+ login: string;
1204
+ name: string | null;
1205
+ email: string | null;
1206
+ };
1051
1207
  submittedAt: string;
1052
1208
  url: string | null;
1053
1209
  }[];
@@ -1105,6 +1261,12 @@ export interface operations {
1105
1261
  } | null;
1106
1262
  milestone: string | null;
1107
1263
  assignees: string[];
1264
+ assigneesResolved?: {
1265
+ id: string;
1266
+ login: string;
1267
+ name: string | null;
1268
+ email: string | null;
1269
+ }[];
1108
1270
  labels: {
1109
1271
  name: string;
1110
1272
  color: string | null;
@@ -1120,6 +1282,12 @@ export interface operations {
1120
1282
  hasConflicts: boolean;
1121
1283
  awaitingReview: boolean;
1122
1284
  author: string | null;
1285
+ authorResolved?: {
1286
+ id: string;
1287
+ login: string;
1288
+ name: string | null;
1289
+ email: string | null;
1290
+ } | null;
1123
1291
  updatedAt: string;
1124
1292
  mergedAt: string | null;
1125
1293
  reviewRequestedAt: string | null;
@@ -1146,6 +1314,12 @@ export interface operations {
1146
1314
  entries: {
1147
1315
  state: "approved" | "changes_requested" | "commented" | "dismissed";
1148
1316
  reviewer: string;
1317
+ reviewerResolved?: {
1318
+ id: string;
1319
+ login: string;
1320
+ name: string | null;
1321
+ email: string | null;
1322
+ };
1149
1323
  submittedAt: string;
1150
1324
  url: string | null;
1151
1325
  }[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cesar-richard/git-connector-sdk",
3
- "version": "1.32.0",
3
+ "version": "1.33.1",
4
4
  "description": "TypeScript SDK for the git-connector v1 API (work items + iterations aggregated from GitHub/GitLab). Version published on npm tracks server releases.",
5
5
  "license": "MIT",
6
6
  "repository": {