githits 0.4.4 → 0.4.6

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.
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  __require,
3
3
  version
4
- } from "./chunk-96tjsv6y.js";
4
+ } from "./chunk-a1hzwt2m.js";
5
5
 
6
6
  // src/services/app-config-paths.ts
7
7
  var APP_DIR = "githits";
@@ -195,7 +195,7 @@ class AuthServiceImpl {
195
195
  }
196
196
  if (url.pathname !== "/callback") {
197
197
  if (callbackHandled) {
198
- sendHtmlResponse(res, 200, successHtml("Authentication already completed."));
198
+ sendHtmlResponse(res, 200, successHtml("You're already signed in."));
199
199
  return;
200
200
  }
201
201
  sendHtmlResponse(res, 404, errorHtml("Invalid callback path.", "Run `githits login` to start authentication."));
@@ -303,11 +303,12 @@ function parseRefreshTokenResponse(data) {
303
303
  expiresIn: d.expires_in || 3600
304
304
  };
305
305
  }
306
- function successHtml(title = "Authentication successful") {
306
+ function successHtml(title = "You're signed in") {
307
307
  return `<!DOCTYPE html>
308
308
  <html><head>
309
309
  <title>GitHits CLI</title>
310
310
  <meta charset="utf-8">
311
+ <meta name="viewport" content="width=device-width, initial-scale=1">
311
312
  <link rel="preconnect" href="https://fonts.googleapis.com">
312
313
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
313
314
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&family=Lexend:wght@600&display=swap" rel="stylesheet">
@@ -369,29 +370,7 @@ function successHtml(title = "Authentication successful") {
369
370
  }
370
371
  .text-muted {
371
372
  color: #abb2bf;
372
- }
373
- .tip {
374
- font-family: 'Inter', sans-serif;
375
- font-weight: 400;
376
- font-size: 14px;
377
- line-height: 20px;
378
- color: #abb2bf;
379
- margin: 0;
380
- text-align: center;
381
- text-wrap: pretty;
382
- }
383
- .tip-label {
384
- font-weight: 600;
385
- color: #ffffff;
386
- }
387
- code {
388
- font-family: 'Consolas', monospace;
389
- font-size: 13px;
390
- background: rgba(255, 255, 255, 0.08);
391
- padding: 1px 6px;
392
- border-radius: 4px;
393
- color: #ffffff;
394
- }
373
+ }${COPY_BTN_CSS}
395
374
  </style>
396
375
  </head>
397
376
  <body>
@@ -403,10 +382,10 @@ function successHtml(title = "Authentication successful") {
403
382
  </div>
404
383
  <div class="message">
405
384
  <h1 class="heading">${escapeHtml(title)}</h1>
406
- <p class="text text-muted">You can close this window and return to the terminal.</p>
385
+ <p class="text text-muted">You can close this window and return to your terminal.</p>
407
386
  </div>
408
387
 
409
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 554 129.3" width="103" height="24" role="img" aria-label="GitHits">
388
+ <svg class="wordmark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 554 129.3" width="103" height="24" role="img" aria-label="GitHits">
410
389
  <title>GitHits</title>
411
390
  <defs>
412
391
  <linearGradient id="wm-grad" x1="234.9" y1="64.7" x2="555.5" y2="64.7" gradientUnits="userSpaceOnUse">
@@ -419,16 +398,30 @@ function successHtml(title = "Authentication successful") {
419
398
  <path d="M239.1,64.8v-24h-18.8V8.5h-25v32.3h-18.8v24h18.8v62.6h25v-62.6h18.8ZM161.1,40.8h-25v86.6h25V40.8ZM91.6,84.6h-26.8v-24h54s1.2,4.3,1.1,12.1c-.3,30.6-25.3,55.5-55.9,55.7h-.5C27.4,128.4-1.6,98.3,0,61.8,1.5,29.6,27.4,3.4,59.6,1.4c21-1.2,40,7.7,52.4,22.4l-17.2,17.2c-7.7-10.1-20.3-16.4-34.3-15.4-19.4,1.4-35,17.1-36.4,36.5-1.6,23,16.6,42.2,39.3,42.2s28-19.7,28-19.7h.2Z" fill="#ff4fae" />
420
399
  </svg>
421
400
 
422
- <p class="tip"><span class="tip-label">TIP:</span> Run <code>npx githits --help</code> to discover what else you can do.</p>
401
+ ${HELP_CTA}
423
402
  </div>
403
+ ${COPY_SCRIPT_HTML}
424
404
  </body></html>`;
425
405
  }
406
+ var KNOWN_OAUTH_ERROR_MESSAGES = {
407
+ access_denied: "Access was denied."
408
+ };
409
+ function describeOauthError(code, description) {
410
+ const mapped = KNOWN_OAUTH_ERROR_MESSAGES[code];
411
+ if (mapped)
412
+ return mapped;
413
+ if (description) {
414
+ return /[.!?]$/.test(description) ? description : `${description}.`;
415
+ }
416
+ return "Something went wrong while signing in.";
417
+ }
426
418
  function evaluateCallback(input) {
427
419
  if (input.error) {
428
420
  const message = input.errorDescription ? `${input.error}: ${input.errorDescription}` : input.error;
421
+ const browserMessage = describeOauthError(input.error, input.errorDescription);
429
422
  return {
430
423
  statusCode: 200,
431
- html: errorHtml(message, "Run `githits login` to try again."),
424
+ html: errorHtml(browserMessage, input.error, RETRY_CTA),
432
425
  result: { type: "oauth_error", message }
433
426
  };
434
427
  }
@@ -436,7 +429,7 @@ function evaluateCallback(input) {
436
429
  if (input.state !== input.expectedState) {
437
430
  return {
438
431
  statusCode: 400,
439
- html: errorHtml("Authentication failed security validation (state mismatch)", "Run `githits login` to try again."),
432
+ html: errorHtml("Sign-in could not be verified for security reasons.", undefined, RETRY_CTA),
440
433
  result: {
441
434
  type: "state_mismatch",
442
435
  message: "Security validation failed (state mismatch)"
@@ -451,19 +444,20 @@ function evaluateCallback(input) {
451
444
  }
452
445
  return {
453
446
  statusCode: 400,
454
- html: errorHtml("Authentication callback was missing required parameters", "Run `githits login` to try again."),
447
+ html: errorHtml("Sign-in did not complete correctly.", undefined, RETRY_CTA),
455
448
  result: {
456
449
  type: "invalid_callback",
457
450
  message: "Authentication callback missing required parameters"
458
451
  }
459
452
  };
460
453
  }
461
- function errorHtml(error, nextStep) {
462
- const nextStepHtml = nextStep ? `<p>${escapeHtml(nextStep)}</p>` : "";
454
+ function errorHtml(error, errorCode, ctaHtml) {
455
+ const errorCodeHtml = errorCode ? `<p class="error-code">Error code: <code>${escapeHtml(errorCode)}</code></p>` : "";
463
456
  return `<!DOCTYPE html>
464
457
  <html><head>
465
458
  <title>GitHits CLI</title>
466
459
  <meta charset="utf-8">
460
+ <meta name="viewport" content="width=device-width, initial-scale=1">
467
461
  <link rel="preconnect" href="https://fonts.googleapis.com">
468
462
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
469
463
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&family=Lexend:wght@600&display=swap" rel="stylesheet">
@@ -529,21 +523,40 @@ function errorHtml(error, nextStep) {
529
523
  .footer-text {
530
524
  font-family: 'Inter', sans-serif;
531
525
  font-weight: 400;
532
- font-size: 14px;
533
- line-height: 20px;
526
+ font-size: 12px;
527
+ line-height: 16px;
534
528
  color: #abb2bf;
535
529
  margin: 0;
536
530
  text-align: center;
537
531
  text-wrap: pretty;
538
532
  }
539
533
  .footer-link {
540
- color: #ffffff;
534
+ color: inherit;
541
535
  text-decoration: underline;
542
536
  text-underline-offset: 2px;
543
537
  }
544
- .footer-link:hover {
538
+ .error-code {
539
+ font-family: 'Inter', sans-serif;
540
+ font-weight: 400;
541
+ font-size: 12px;
542
+ line-height: 16px;
545
543
  color: #abb2bf;
544
+ opacity: 0.7;
545
+ margin: 4px 0 0;
546
+ text-align: center;
547
+ }
548
+ .error-code code {
549
+ font-size: 11px;
550
+ padding: 0 5px;
546
551
  }
552
+ code {
553
+ font-family: 'Consolas', monospace;
554
+ font-size: 13px;
555
+ background: rgba(255, 255, 255, 0.08);
556
+ padding: 1px 6px;
557
+ border-radius: 4px;
558
+ color: #ffffff;
559
+ }${COPY_BTN_CSS}
547
560
  </style>
548
561
  </head>
549
562
  <body>
@@ -556,13 +569,14 @@ function errorHtml(error, nextStep) {
556
569
  </div>
557
570
 
558
571
  <div class="message">
559
- <h1 class="heading">Authentication failed</h1>
572
+ <h1 class="heading">Sign-in failed</h1>
560
573
  <p class="text text-muted">${escapeHtml(error)}</p>
574
+ ${errorCodeHtml}
561
575
  </div>
562
576
 
563
- ${nextStepHtml}
577
+ ${ctaHtml ?? ""}
564
578
 
565
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 554 129.3" width="103" height="24" role="img" aria-label="GitHits">
579
+ <svg class="wordmark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 554 129.3" width="103" height="24" role="img" aria-label="GitHits">
566
580
  <title>GitHits</title>
567
581
  <defs>
568
582
  <linearGradient id="wm-grad" x1="234.9" y1="64.7" x2="555.5" y2="64.7" gradientUnits="userSpaceOnUse">
@@ -577,6 +591,7 @@ function errorHtml(error, nextStep) {
577
591
 
578
592
  <p class="footer-text">Having trouble? Check our <a class="footer-link" href="https://app.githits.com/docs/" target="_blank" rel="noopener noreferrer">documentation</a> or contact <a class="footer-link" href="mailto:support@githits.com">support</a>.</p>
579
593
  </div>
594
+ ${COPY_SCRIPT_HTML}
580
595
  </body></html>`;
581
596
  }
582
597
  function sendHtmlResponse(res, statusCode, html) {
@@ -597,6 +612,108 @@ function closeServer(server) {
597
612
  });
598
613
  });
599
614
  }
615
+ var COPY_ICON_SVG = `<svg class="githits-cli-icon githits-cli-icon-copy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>`;
616
+ var CHECK_ICON_SVG = `<svg class="githits-cli-icon githits-cli-icon-check" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="20 6 9 17 4 12"></polyline></svg>`;
617
+ function commandButton(cmd) {
618
+ const escaped = escapeHtml(cmd);
619
+ return `<button type="button" class="githits-cli-btn" data-copy="${escaped}" aria-label="Copy command: ${escaped}"><span class="githits-cli-cmd">${escaped}</span>${COPY_ICON_SVG}${CHECK_ICON_SVG}</button>`;
620
+ }
621
+ function ctaBlock(introHtml, commands) {
622
+ const buttons = commands.map(commandButton).join(`
623
+ `);
624
+ return `<div class="cli-cta">
625
+ <p class="tip">${introHtml}</p>
626
+ ${buttons}
627
+ </div>`;
628
+ }
629
+ var COPY_BTN_CSS = `
630
+ .wordmark {
631
+ margin: 16px 0;
632
+ }
633
+ .cli-cta {
634
+ display: flex;
635
+ flex-direction: column;
636
+ align-items: center;
637
+ gap: 12px;
638
+ margin: 16px 0 0;
639
+ }
640
+ .wordmark + .cli-cta {
641
+ margin-top: 0;
642
+ }
643
+ .tip {
644
+ font-family: 'Inter', sans-serif;
645
+ font-weight: 400;
646
+ font-size: 14px;
647
+ line-height: 20px;
648
+ color: #d5d9df;
649
+ margin: 0;
650
+ text-align: center;
651
+ text-wrap: pretty;
652
+ }
653
+ .githits-cli-btn {
654
+ display: inline-flex;
655
+ align-items: center;
656
+ gap: 0.5rem;
657
+ background-color: rgba(255, 255, 255, 0.08);
658
+ border: none;
659
+ border-radius: 0.5rem;
660
+ padding: 1rem 1.25rem;
661
+ font-family: Consolas, ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
662
+ font-size: 14px;
663
+ font-weight: 500;
664
+ color: #abb2bf;
665
+ cursor: pointer;
666
+ line-height: 1;
667
+ transition: background-color 0.2s ease, transform 0.1s ease, color 0.2s ease;
668
+ }
669
+ .githits-cli-btn:hover {
670
+ color: #d5d9df;
671
+ }
672
+ .githits-cli-btn:active {
673
+ transform: scale(0.98);
674
+ }
675
+ .githits-cli-btn:focus-visible {
676
+ outline: 2px solid #abb2bf;
677
+ outline-offset: 2px;
678
+ }
679
+ .githits-cli-cmd {
680
+ white-space: nowrap;
681
+ }
682
+ .githits-cli-icon {
683
+ width: 14px;
684
+ height: 14px;
685
+ color: #abb2bf;
686
+ flex-shrink: 0;
687
+ }
688
+ .githits-cli-btn.copied .githits-cli-icon-copy { display: none; }
689
+ .githits-cli-btn:not(.copied) .githits-cli-icon-check { display: none; }
690
+ .githits-cli-btn.copied .githits-cli-icon { color: #abb2bf; }`;
691
+ var COPY_SCRIPT_HTML = `<script>
692
+ (function() {
693
+ var timers = new WeakMap();
694
+ var buttons = document.querySelectorAll('.githits-cli-btn');
695
+ for (var i = 0; i < buttons.length; i++) {
696
+ buttons[i].addEventListener('click', function(e) {
697
+ var target = e.currentTarget;
698
+ var text = target.getAttribute('data-copy');
699
+ if (!text || !navigator.clipboard) return;
700
+ navigator.clipboard.writeText(text).then(function() {
701
+ target.classList.add('copied');
702
+ var existing = timers.get(target);
703
+ if (existing) clearTimeout(existing);
704
+ timers.set(target, setTimeout(function() {
705
+ target.classList.remove('copied');
706
+ timers.delete(target);
707
+ }, 1500));
708
+ });
709
+ });
710
+ }
711
+ })();
712
+ </script>`;
713
+ var RETRY_CTA = ctaBlock("To try again, run these commands in your terminal:", ["npx githits@latest logout", "npx githits@latest login"]);
714
+ var HELP_CTA = ctaBlock("Explore available commands with:", [
715
+ "npx githits@latest --help"
716
+ ]);
600
717
  function escapeHtml(text) {
601
718
  return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
602
719
  }
@@ -1400,11 +1517,17 @@ class GitHitsServiceImpl {
1400
1517
  method: "POST",
1401
1518
  headers: this.headers(),
1402
1519
  body: JSON.stringify({
1520
+ ...params.exampleId !== undefined && {
1521
+ example_id: params.exampleId
1522
+ },
1403
1523
  ...params.solutionId !== undefined && {
1404
1524
  solution_id: params.solutionId
1405
1525
  },
1406
1526
  accepted: params.accepted,
1407
- feedback_text: params.feedbackText ?? null
1527
+ feedback_text: params.feedbackText ?? null,
1528
+ ...params.toolName !== undefined && {
1529
+ tool_name: params.toolName
1530
+ }
1408
1531
  })
1409
1532
  });
1410
1533
  if (!response.ok) {
@@ -1482,10 +1605,14 @@ class CodeNavigationGraphQLError extends Error {
1482
1605
  class CodeNavigationIndexingError extends Error {
1483
1606
  indexingRef;
1484
1607
  availableVersions;
1485
- constructor(message, indexingRef, availableVersions) {
1608
+ availableRefs;
1609
+ targetResolution;
1610
+ constructor(message, indexingRef, availableVersions, availableRefs, targetResolution) {
1486
1611
  super(message);
1487
1612
  this.indexingRef = indexingRef;
1488
1613
  this.availableVersions = availableVersions;
1614
+ this.availableRefs = availableRefs;
1615
+ this.targetResolution = targetResolution;
1489
1616
  this.name = "CodeNavigationIndexingError";
1490
1617
  }
1491
1618
  }
@@ -1570,6 +1697,63 @@ class CodeNavigationBackendError extends Error {
1570
1697
  this.name = "CodeNavigationBackendError";
1571
1698
  }
1572
1699
  }
1700
+ var TARGET_RESOLUTION_AVAILABLE_REFS_SELECTION = `
1701
+ availableRefs {
1702
+ version
1703
+ ref
1704
+ }`;
1705
+ var TARGET_RESOLUTION_SELECTION = `
1706
+ targetResolution {
1707
+ requested {
1708
+ kind
1709
+ registry
1710
+ packageName
1711
+ version
1712
+ repoUrl
1713
+ gitRef
1714
+ commitSha
1715
+ }
1716
+ resolvedRequested {
1717
+ kind
1718
+ registry
1719
+ packageName
1720
+ version
1721
+ repoUrl
1722
+ gitRef
1723
+ commitSha
1724
+ }
1725
+ served {
1726
+ kind
1727
+ registry
1728
+ packageName
1729
+ version
1730
+ repoUrl
1731
+ gitRef
1732
+ commitSha
1733
+ }
1734
+ freshness
1735
+ freshnessReason
1736
+ indexingRef
1737
+ availableVersions {
1738
+ version
1739
+ ref
1740
+ }
1741
+ ${TARGET_RESOLUTION_AVAILABLE_REFS_SELECTION}
1742
+ }`;
1743
+ var CODE_CONTEXT_AVAILABLE_VERSIONS_SELECTION = `
1744
+ availableVersions {
1745
+ version
1746
+ ref
1747
+ }`;
1748
+ var DISCOVERY_TARGET_PROGRESS_RETRY_SELECTION = `
1749
+ availableVersions {
1750
+ version
1751
+ ref
1752
+ }
1753
+ availableRefs {
1754
+ version
1755
+ ref
1756
+ }`;
1573
1757
  var UNIFIED_SEARCH_QUERY = `
1574
1758
  query UnifiedSearch(
1575
1759
  $targets: [SearchPackageInput!]!
@@ -1646,6 +1830,7 @@ query UnifiedSearch(
1646
1830
  requestedTargetLabel
1647
1831
  freshTargetLabel
1648
1832
  servedTargetLabel
1833
+ ${TARGET_RESOLUTION_SELECTION}
1649
1834
  indexingStatus
1650
1835
  codeIndexState
1651
1836
  resultCount
@@ -1692,6 +1877,8 @@ query UnifiedSearch(
1692
1877
  freshness
1693
1878
  indexingRef
1694
1879
  requestedRefKind
1880
+ ${TARGET_RESOLUTION_SELECTION}
1881
+ ${DISCOVERY_TARGET_PROGRESS_RETRY_SELECTION}
1695
1882
  }
1696
1883
  expiresAt
1697
1884
  }
@@ -1733,6 +1920,8 @@ query UnifiedSearchStatus($searchRef: String!, $includeResults: Boolean!) {
1733
1920
  freshness
1734
1921
  indexingRef
1735
1922
  requestedRefKind
1923
+ ${TARGET_RESOLUTION_SELECTION}
1924
+ ${DISCOVERY_TARGET_PROGRESS_RETRY_SELECTION}
1736
1925
  }
1737
1926
  expiresAt
1738
1927
  results {
@@ -1788,6 +1977,7 @@ query UnifiedSearchStatus($searchRef: String!, $includeResults: Boolean!) {
1788
1977
  requestedTargetLabel
1789
1978
  freshTargetLabel
1790
1979
  servedTargetLabel
1980
+ ${TARGET_RESOLUTION_SELECTION}
1791
1981
  indexingStatus
1792
1982
  codeIndexState
1793
1983
  resultCount
@@ -1853,6 +2043,25 @@ var availableVersionSchema = z2.object({
1853
2043
  version: z2.string().nullable().optional(),
1854
2044
  ref: z2.string()
1855
2045
  });
2046
+ var targetResolutionIdentitySchema = z2.object({
2047
+ kind: z2.string().nullable().optional(),
2048
+ registry: z2.string().nullable().optional(),
2049
+ packageName: z2.string().nullable().optional(),
2050
+ version: z2.string().nullable().optional(),
2051
+ repoUrl: z2.string().nullable().optional(),
2052
+ gitRef: z2.string().nullable().optional(),
2053
+ commitSha: z2.string().nullable().optional()
2054
+ }).nullable().optional();
2055
+ var targetResolutionSchema = z2.object({
2056
+ requested: targetResolutionIdentitySchema,
2057
+ resolvedRequested: targetResolutionIdentitySchema,
2058
+ served: targetResolutionIdentitySchema,
2059
+ freshness: z2.string().nullable().optional(),
2060
+ freshnessReason: z2.string().nullable().optional(),
2061
+ indexingRef: z2.string().nullable().optional(),
2062
+ availableVersions: z2.array(availableVersionSchema).nullable().optional(),
2063
+ availableRefs: z2.array(availableVersionSchema).nullable().optional()
2064
+ }).nullable().optional();
1856
2065
  var unifiedSearchSourceSchema = z2.enum(["AUTO", "DOCS", "CODE", "SYMBOL"]);
1857
2066
  var unifiedSearchResultTypeSchema = z2.enum([
1858
2067
  "DOCUMENTATION_PAGE",
@@ -1909,6 +2118,7 @@ var unifiedSearchSourceStatusSchema = z2.object({
1909
2118
  requestedTargetLabel: z2.string().nullable().optional(),
1910
2119
  freshTargetLabel: z2.string().nullable().optional(),
1911
2120
  servedTargetLabel: z2.string().nullable().optional(),
2121
+ targetResolution: targetResolutionSchema,
1912
2122
  indexingStatus: z2.string().nullable().optional(),
1913
2123
  codeIndexState: z2.string().nullable().optional(),
1914
2124
  resultCount: z2.number().int().nullable().optional(),
@@ -1950,7 +2160,10 @@ var unifiedSearchProgressTargetSchema = z2.object({
1950
2160
  served: z2.string().nullable().optional(),
1951
2161
  freshness: z2.string().nullable().optional(),
1952
2162
  indexingRef: z2.string().nullable().optional(),
1953
- requestedRefKind: z2.string().nullable().optional()
2163
+ requestedRefKind: z2.string().nullable().optional(),
2164
+ targetResolution: targetResolutionSchema,
2165
+ availableVersions: z2.array(availableVersionSchema).nullable().optional(),
2166
+ availableRefs: z2.array(availableVersionSchema).nullable().optional()
1954
2167
  });
1955
2168
  var unifiedSearchRequestedTargetSchema = z2.object({
1956
2169
  registry: z2.string().nullable().optional(),
@@ -2010,6 +2223,7 @@ var listRepoFilesResponseSchema = z2.object({
2010
2223
  hasMore: z2.boolean(),
2011
2224
  indexedVersion: z2.string().nullable().optional(),
2012
2225
  resolution: navigationResolutionSchema,
2226
+ targetResolution: targetResolutionSchema,
2013
2227
  diagnostics: navigationDiagnosticsSchema,
2014
2228
  codeIndexState: z2.string(),
2015
2229
  indexingRef: z2.string().nullable().optional(),
@@ -2078,6 +2292,7 @@ query ListRepoFiles(
2078
2292
  resolvedRef
2079
2293
  commitSha
2080
2294
  }
2295
+ ${TARGET_RESOLUTION_SELECTION}
2081
2296
  diagnostics {
2082
2297
  hint
2083
2298
  }
@@ -2100,7 +2315,9 @@ var codeContextResponseSchema = z2.object({
2100
2315
  gitRef: z2.string().nullable().optional(),
2101
2316
  isBinary: z2.boolean().nullable().optional(),
2102
2317
  codeIndexState: z2.string(),
2103
- indexingRef: z2.string().nullable().optional()
2318
+ indexingRef: z2.string().nullable().optional(),
2319
+ availableVersions: z2.array(availableVersionSchema).nullable().optional(),
2320
+ targetResolution: targetResolutionSchema
2104
2321
  });
2105
2322
  var fetchCodeContextGraphQLResponseSchema = z2.object({
2106
2323
  data: z2.object({
@@ -2142,6 +2359,8 @@ query FetchCodeContext(
2142
2359
  isBinary
2143
2360
  codeIndexState
2144
2361
  indexingRef
2362
+ ${CODE_CONTEXT_AVAILABLE_VERSIONS_SELECTION}
2363
+ ${TARGET_RESOLUTION_SELECTION}
2145
2364
  }
2146
2365
  }`;
2147
2366
  var grepRepoMatchSchema = z2.object({
@@ -2192,6 +2411,7 @@ var grepRepoResponseSchema = z2.object({
2192
2411
  uniqueFilesMatched: z2.number().int(),
2193
2412
  indexedVersion: z2.string().nullable().optional(),
2194
2413
  resolution: navigationResolutionSchema,
2414
+ targetResolution: targetResolutionSchema,
2195
2415
  codeIndexState: z2.string(),
2196
2416
  indexingRef: z2.string().nullable().optional(),
2197
2417
  availableVersions: z2.array(availableVersionSchema).nullable().optional()
@@ -2300,6 +2520,7 @@ query GrepRepo(
2300
2520
  resolvedRef
2301
2521
  commitSha
2302
2522
  }
2523
+ ${TARGET_RESOLUTION_SELECTION}
2303
2524
  codeIndexState
2304
2525
  indexingRef
2305
2526
  availableVersions {
@@ -2331,6 +2552,35 @@ class CodeNavigationServiceImpl {
2331
2552
  this.tokenProvider = tokenProvider;
2332
2553
  this.fetchFn = fetchFn;
2333
2554
  }
2555
+ async postGraphqlWithTargetResolutionFallback(input) {
2556
+ const response = await postPkgseerGraphql({
2557
+ endpointUrl: this.codeNavigationUrl,
2558
+ token: input.token,
2559
+ query: input.query,
2560
+ variables: input.variables,
2561
+ fetchFn: this.fetchFn
2562
+ });
2563
+ if (response.status < 200 || response.status >= 300)
2564
+ return response;
2565
+ if (!hasSchemaMismatchErrors(response.parsedBody))
2566
+ return response;
2567
+ for (const fallbackQuery of buildTargetResolutionFallbackQueries(input.query)) {
2568
+ debugLog("code-nav", {
2569
+ event: "target-resolution-query-fallback"
2570
+ });
2571
+ const fallbackResponse = await postPkgseerGraphql({
2572
+ endpointUrl: this.codeNavigationUrl,
2573
+ token: input.token,
2574
+ query: fallbackQuery,
2575
+ variables: input.variables,
2576
+ fetchFn: this.fetchFn
2577
+ });
2578
+ if (!hasSchemaMismatchErrors(fallbackResponse.parsedBody)) {
2579
+ return fallbackResponse;
2580
+ }
2581
+ }
2582
+ return response;
2583
+ }
2334
2584
  async search(params) {
2335
2585
  return executeWithTokenRefresh({
2336
2586
  getToken: () => this.tokenProvider.getToken(),
@@ -2371,12 +2621,10 @@ class CodeNavigationServiceImpl {
2371
2621
  debugUnifiedSearchRequest(variables);
2372
2622
  debugGraphqlWireRequest("search", UNIFIED_SEARCH_QUERY, variables);
2373
2623
  try {
2374
- response = await postPkgseerGraphql({
2375
- endpointUrl: this.codeNavigationUrl,
2624
+ response = await this.postGraphqlWithTargetResolutionFallback({
2376
2625
  token,
2377
2626
  query: UNIFIED_SEARCH_QUERY,
2378
- variables,
2379
- fetchFn: this.fetchFn
2627
+ variables
2380
2628
  });
2381
2629
  } catch (cause) {
2382
2630
  if (cause instanceof PkgseerTransportError) {
@@ -2403,15 +2651,13 @@ class CodeNavigationServiceImpl {
2403
2651
  async executeUnifiedSearchStatus(token, searchRef) {
2404
2652
  let response;
2405
2653
  try {
2406
- response = await postPkgseerGraphql({
2407
- endpointUrl: this.codeNavigationUrl,
2654
+ response = await this.postGraphqlWithTargetResolutionFallback({
2408
2655
  token,
2409
2656
  query: UNIFIED_SEARCH_STATUS_QUERY,
2410
2657
  variables: {
2411
2658
  searchRef,
2412
2659
  includeResults: true
2413
- },
2414
- fetchFn: this.fetchFn
2660
+ }
2415
2661
  });
2416
2662
  } catch (cause) {
2417
2663
  if (cause instanceof PkgseerTransportError) {
@@ -2486,7 +2732,7 @@ class CodeNavigationServiceImpl {
2486
2732
  }
2487
2733
  switch (code) {
2488
2734
  case "PACKAGE_INDEXING":
2489
- return new CodeNavigationIndexingError(this.createIndexingMessage(indexingRef), indexingRef, parseAvailableVersions(extensions));
2735
+ return new CodeNavigationIndexingError(this.createIndexingMessage(indexingRef), indexingRef, parseAvailableVersions(extensions), parseAvailableRefs(extensions), parseTargetResolution(extensions));
2490
2736
  case "GREP_PATTERN_TOO_SHORT":
2491
2737
  case "GREP_PATTERN_TOO_LONG":
2492
2738
  case "GREP_PATTERN_INVALID":
@@ -2633,6 +2879,7 @@ class CodeNavigationServiceImpl {
2633
2879
  requestedTargetLabel: entry.requestedTargetLabel ?? undefined,
2634
2880
  freshTargetLabel: entry.freshTargetLabel ?? undefined,
2635
2881
  servedTargetLabel: entry.servedTargetLabel ?? undefined,
2882
+ targetResolution: normaliseTargetResolution(entry.targetResolution),
2636
2883
  indexingStatus: entry.indexingStatus ?? undefined,
2637
2884
  codeIndexState: entry.codeIndexState ?? undefined,
2638
2885
  resultCount: entry.resultCount ?? undefined,
@@ -2674,17 +2921,18 @@ class CodeNavigationServiceImpl {
2674
2921
  served: target.served ?? undefined,
2675
2922
  freshness: target.freshness ?? undefined,
2676
2923
  indexingRef: target.indexingRef ?? undefined,
2677
- requestedRefKind: normaliseRequestedRefKind(target.requestedRefKind)
2924
+ requestedRefKind: normaliseRequestedRefKind(target.requestedRefKind),
2925
+ targetResolution: normaliseTargetResolution(target.targetResolution),
2926
+ availableVersions: normaliseAvailableVersions(target.availableVersions),
2927
+ availableRefs: normaliseAvailableVersions(target.availableRefs)
2678
2928
  })),
2679
2929
  expiresAt: progress.expiresAt ?? undefined
2680
2930
  };
2681
2931
  }
2682
2932
  throwIfIndexing(data) {
2683
2933
  if (data.codeIndexState === "INDEXING") {
2684
- throw new CodeNavigationIndexingError(this.createIndexingMessage(data.indexingRef ?? undefined), data.indexingRef ?? undefined, data.availableVersions?.map((entry) => ({
2685
- version: entry.version ?? undefined,
2686
- ref: entry.ref
2687
- })));
2934
+ const targetResolution = normaliseTargetResolution(data.targetResolution);
2935
+ throw new CodeNavigationIndexingError(this.createIndexingMessage(data.indexingRef ?? targetResolution?.indexingRef), data.indexingRef ?? targetResolution?.indexingRef, normaliseAvailableVersions(data.availableVersions) ?? targetResolution?.availableVersions, targetResolution?.availableRefs, targetResolution);
2688
2936
  }
2689
2937
  }
2690
2938
  async listFiles(params) {
@@ -2698,8 +2946,7 @@ class CodeNavigationServiceImpl {
2698
2946
  async executeListFiles(token, params) {
2699
2947
  let response;
2700
2948
  try {
2701
- response = await postPkgseerGraphql({
2702
- endpointUrl: this.codeNavigationUrl,
2949
+ response = await this.postGraphqlWithTargetResolutionFallback({
2703
2950
  token,
2704
2951
  query: LIST_REPO_FILES_QUERY,
2705
2952
  variables: {
@@ -2724,8 +2971,7 @@ class CodeNavigationServiceImpl {
2724
2971
  includeHidden: params.includeHidden,
2725
2972
  limit: params.limit,
2726
2973
  waitTimeoutMs: params.waitTimeoutMs
2727
- },
2728
- fetchFn: this.fetchFn
2974
+ }
2729
2975
  });
2730
2976
  } catch (cause) {
2731
2977
  if (cause instanceof PkgseerTransportError) {
@@ -2765,6 +3011,7 @@ class CodeNavigationServiceImpl {
2765
3011
  resolvedRef: data.resolution.resolvedRef ?? undefined,
2766
3012
  commitSha: data.resolution.commitSha ?? undefined
2767
3013
  } : undefined,
3014
+ targetResolution: normaliseTargetResolution(data.targetResolution),
2768
3015
  hint: data.diagnostics?.hint ?? undefined
2769
3016
  };
2770
3017
  }
@@ -2779,8 +3026,7 @@ class CodeNavigationServiceImpl {
2779
3026
  async executeReadFile(token, params) {
2780
3027
  let response;
2781
3028
  try {
2782
- response = await postPkgseerGraphql({
2783
- endpointUrl: this.codeNavigationUrl,
3029
+ response = await this.postGraphqlWithTargetResolutionFallback({
2784
3030
  token,
2785
3031
  query: FETCH_CODE_CONTEXT_QUERY,
2786
3032
  variables: {
@@ -2793,8 +3039,7 @@ class CodeNavigationServiceImpl {
2793
3039
  startLine: params.startLine,
2794
3040
  endLine: params.endLine,
2795
3041
  waitTimeoutMs: params.waitTimeoutMs
2796
- },
2797
- fetchFn: this.fetchFn
3042
+ }
2798
3043
  });
2799
3044
  } catch (cause) {
2800
3045
  if (cause instanceof PkgseerTransportError) {
@@ -2816,10 +3061,7 @@ class CodeNavigationServiceImpl {
2816
3061
  if (!data) {
2817
3062
  throw new MalformedCodeNavigationResponseError("Malformed response from code navigation service.");
2818
3063
  }
2819
- this.throwIfIndexing({
2820
- codeIndexState: data.codeIndexState,
2821
- indexingRef: data.indexingRef
2822
- });
3064
+ this.throwIfIndexing(data);
2823
3065
  return {
2824
3066
  filePath: data.filePath ?? undefined,
2825
3067
  language: data.language ?? undefined,
@@ -2827,7 +3069,9 @@ class CodeNavigationServiceImpl {
2827
3069
  startLine: data.startLine ?? undefined,
2828
3070
  endLine: data.endLine ?? undefined,
2829
3071
  content: data.content ?? undefined,
2830
- isBinary: data.isBinary ?? undefined
3072
+ isBinary: data.isBinary ?? undefined,
3073
+ targetResolution: normaliseTargetResolution(data.targetResolution),
3074
+ availableVersions: normaliseAvailableVersions(data.availableVersions)
2831
3075
  };
2832
3076
  }
2833
3077
  async grepRepo(params) {
@@ -2841,8 +3085,7 @@ class CodeNavigationServiceImpl {
2841
3085
  async executeGrepRepo(token, params) {
2842
3086
  let response;
2843
3087
  try {
2844
- response = await postPkgseerGraphql({
2845
- endpointUrl: this.codeNavigationUrl,
3088
+ response = await this.postGraphqlWithTargetResolutionFallback({
2846
3089
  token,
2847
3090
  query: buildGrepRepoQuery(params.symbolFields),
2848
3091
  variables: {
@@ -2869,8 +3112,7 @@ class CodeNavigationServiceImpl {
2869
3112
  maxMatchesPerFile: params.maxMatchesPerFile,
2870
3113
  cursor: params.cursor,
2871
3114
  symbolFields: params.symbolFields
2872
- },
2873
- fetchFn: this.fetchFn
3115
+ }
2874
3116
  });
2875
3117
  } catch (cause) {
2876
3118
  if (cause instanceof PkgseerTransportError) {
@@ -2939,7 +3181,8 @@ class CodeNavigationServiceImpl {
2939
3181
  requestedRef: data.resolution.requestedRef ?? undefined,
2940
3182
  resolvedRef: data.resolution.resolvedRef ?? undefined,
2941
3183
  commitSha: data.resolution.commitSha ?? undefined
2942
- } : undefined
3184
+ } : undefined,
3185
+ targetResolution: normaliseTargetResolution(data.targetResolution)
2943
3186
  };
2944
3187
  }
2945
3188
  }
@@ -2957,6 +3200,31 @@ function parseDetail2(body) {
2957
3200
  }
2958
3201
  return;
2959
3202
  }
3203
+ function buildTargetResolutionFallbackQueries(query) {
3204
+ const candidates = [
3205
+ query.replaceAll(TARGET_RESOLUTION_AVAILABLE_REFS_SELECTION, ""),
3206
+ query.replaceAll(DISCOVERY_TARGET_PROGRESS_RETRY_SELECTION, ""),
3207
+ query.replaceAll(CODE_CONTEXT_AVAILABLE_VERSIONS_SELECTION, ""),
3208
+ query.replaceAll(TARGET_RESOLUTION_SELECTION, "").replaceAll(DISCOVERY_TARGET_PROGRESS_RETRY_SELECTION, "").replaceAll(CODE_CONTEXT_AVAILABLE_VERSIONS_SELECTION, "")
3209
+ ];
3210
+ return candidates.filter((candidate, index, all) => candidate !== query && all.indexOf(candidate) === index);
3211
+ }
3212
+ function hasSchemaMismatchErrors(parsedBody) {
3213
+ if (!parsedBody || typeof parsedBody !== "object")
3214
+ return false;
3215
+ const errors = parsedBody.errors;
3216
+ if (!Array.isArray(errors))
3217
+ return false;
3218
+ return errors.some((entry) => {
3219
+ if (!entry || typeof entry !== "object")
3220
+ return false;
3221
+ const error = entry;
3222
+ if (typeof error.message !== "string")
3223
+ return false;
3224
+ const code = typeof error.extensions?.code === "string" ? error.extensions.code : undefined;
3225
+ return isGraphQLSchemaMismatchError({ message: error.message, code });
3226
+ });
3227
+ }
2960
3228
  function getPrimaryExtensions(errors) {
2961
3229
  for (const error of errors) {
2962
3230
  if (error.extensions && Object.keys(error.extensions).length > 0) {
@@ -2975,6 +3243,20 @@ function getGraphQLIndexingRef(errors) {
2975
3243
  }
2976
3244
  function parseAvailableVersions(extensions) {
2977
3245
  const raw = extensions?.available_versions ?? extensions?.availableVersions;
3246
+ return parseAvailableArtifacts(raw);
3247
+ }
3248
+ function parseAvailableRefs(extensions) {
3249
+ const raw = extensions?.available_refs ?? extensions?.availableRefs;
3250
+ return parseAvailableArtifacts(raw);
3251
+ }
3252
+ function parseTargetResolution(extensions) {
3253
+ const raw = extensions?.target_resolution ?? extensions?.targetResolution;
3254
+ const parsed = targetResolutionSchema.safeParse(raw);
3255
+ if (!parsed.success)
3256
+ return;
3257
+ return normaliseTargetResolution(parsed.data);
3258
+ }
3259
+ function parseAvailableArtifacts(raw) {
2978
3260
  if (!Array.isArray(raw))
2979
3261
  return;
2980
3262
  const parsed = [];
@@ -2991,6 +3273,48 @@ function parseAvailableVersions(extensions) {
2991
3273
  }
2992
3274
  return parsed.length > 0 ? parsed : undefined;
2993
3275
  }
3276
+ function normaliseAvailableVersions(entries) {
3277
+ if (!entries || entries.length === 0)
3278
+ return;
3279
+ return entries.map((entry) => ({
3280
+ version: entry.version ?? undefined,
3281
+ ref: entry.ref
3282
+ }));
3283
+ }
3284
+ function normaliseTargetResolution(resolution) {
3285
+ if (!resolution)
3286
+ return;
3287
+ return {
3288
+ requested: normaliseTargetResolutionIdentity(resolution.requested),
3289
+ resolvedRequested: normaliseTargetResolutionIdentity(resolution.resolvedRequested),
3290
+ served: normaliseTargetResolutionIdentity(resolution.served),
3291
+ freshness: resolution.freshness ?? undefined,
3292
+ freshnessReason: resolution.freshnessReason ?? undefined,
3293
+ indexingRef: resolution.indexingRef ?? undefined,
3294
+ availableVersions: normaliseAvailableVersions(resolution.availableVersions) ?? [],
3295
+ availableRefs: normaliseAvailableVersions(resolution.availableRefs) ?? []
3296
+ };
3297
+ }
3298
+ function normaliseTargetResolutionIdentity(identity) {
3299
+ if (!identity)
3300
+ return;
3301
+ const out = {};
3302
+ if (identity.kind)
3303
+ out.kind = identity.kind;
3304
+ if (identity.registry)
3305
+ out.registry = identity.registry;
3306
+ if (identity.packageName)
3307
+ out.packageName = identity.packageName;
3308
+ if (identity.version)
3309
+ out.version = identity.version;
3310
+ if (identity.repoUrl)
3311
+ out.repoUrl = identity.repoUrl;
3312
+ if (identity.gitRef)
3313
+ out.gitRef = identity.gitRef;
3314
+ if (identity.commitSha)
3315
+ out.commitSha = identity.commitSha;
3316
+ return Object.keys(out).length > 0 ? out : undefined;
3317
+ }
2994
3318
  function isAuthMessage(message) {
2995
3319
  const lower = message.toLowerCase();
2996
3320
  return lower.includes("unauthorized") || lower.includes("forbidden") || lower.includes("permission") || lower.includes("authentication");
@@ -3062,14 +3386,31 @@ function getEnvApiToken() {
3062
3386
  }
3063
3387
  // src/services/exec-service.ts
3064
3388
  import { spawn } from "node:child_process";
3389
+ function isWindowsAbsolutePath(command) {
3390
+ return /^[a-zA-Z]:[\\/]/.test(command) || command.startsWith("\\\\");
3391
+ }
3392
+ function normalizeSpawnCommand(command, args, platform = process.platform) {
3393
+ if (platform !== "win32") {
3394
+ return { command, args };
3395
+ }
3396
+ if (isWindowsAbsolutePath(command) && /\s/.test(command)) {
3397
+ return {
3398
+ command: `"${command.replaceAll('"', "\\\"")}"`,
3399
+ args,
3400
+ shell: true
3401
+ };
3402
+ }
3403
+ return { command, args, shell: true };
3404
+ }
3065
3405
 
3066
3406
  class ExecServiceImpl {
3067
3407
  async exec(command, args) {
3068
3408
  return new Promise((resolve, reject) => {
3069
- const child = spawn(command, args, {
3409
+ const spawnCommand = normalizeSpawnCommand(command, args);
3410
+ const child = spawn(spawnCommand.command, spawnCommand.args, {
3070
3411
  stdio: ["ignore", "pipe", "pipe"],
3071
3412
  env: { ...process.env },
3072
- ...process.platform === "win32" && { shell: true }
3413
+ ...spawnCommand.shell !== undefined && { shell: spawnCommand.shell }
3073
3414
  });
3074
3415
  const stdoutChunks = [];
3075
3416
  const stderrChunks = [];
@@ -4167,7 +4508,10 @@ query PackageSummary($registry: Registry!, $name: String!) {
4167
4508
  var packageVersionIdentitySchema = z3.object({
4168
4509
  name: z3.string().nullable().optional(),
4169
4510
  registry: z3.string().nullable().optional(),
4170
- version: z3.string().nullable().optional()
4511
+ version: z3.string().nullable().optional(),
4512
+ publishedAt: z3.string().nullable().optional(),
4513
+ deprecated: z3.boolean().nullable().optional(),
4514
+ deprecationReason: z3.string().nullable().optional()
4171
4515
  });
4172
4516
  var vulnerabilityDetailSchema = z3.object({
4173
4517
  osvId: z3.string().nullable().optional(),
@@ -4291,6 +4635,86 @@ var dependencyGraphSchema = z3.object({
4291
4635
  nodes: z3.array(dependencyGraphNodeSchema),
4292
4636
  edges: z3.array(dependencyGraphEdgeSchema)
4293
4637
  });
4638
+ var vulnerabilityCountSummarySchema = z3.object({
4639
+ totalVulnerabilities: z3.number().int(),
4640
+ critical: z3.number().int(),
4641
+ high: z3.number().int(),
4642
+ medium: z3.number().int(),
4643
+ low: z3.number().int(),
4644
+ unknown: z3.number().int()
4645
+ });
4646
+ var vulnerabilitySummaryDetailSchema = z3.object({
4647
+ osvId: z3.string().nullable().optional(),
4648
+ registry: z3.string().nullable().optional(),
4649
+ packageName: z3.string().nullable().optional(),
4650
+ summary: z3.string().nullable().optional(),
4651
+ severityScore: z3.number().nullable().optional(),
4652
+ severityType: z3.string().nullable().optional(),
4653
+ affectedVersionRanges: z3.array(z3.string()).nullable().optional(),
4654
+ fixedInVersions: z3.array(z3.string()).nullable().optional(),
4655
+ publishedAt: z3.string().nullable().optional(),
4656
+ modifiedAt: z3.string().nullable().optional(),
4657
+ withdrawnAt: z3.string().nullable().optional(),
4658
+ aliases: z3.array(z3.string()).nullable().optional(),
4659
+ isMalicious: z3.boolean().nullable().optional()
4660
+ });
4661
+ var transitiveDependencyVulnerabilitySchema = z3.object({
4662
+ version: z3.string(),
4663
+ affectsResolvedVersion: z3.boolean(),
4664
+ matchedAffectedVersionRanges: z3.array(z3.string()),
4665
+ fixVersionsAboveResolved: z3.array(z3.string()),
4666
+ nearestFixedVersion: z3.string().nullable().optional(),
4667
+ advisory: vulnerabilitySummaryDetailSchema
4668
+ });
4669
+ var transitiveVulnerablePackageSchema = z3.object({
4670
+ registry: z3.string(),
4671
+ name: z3.string(),
4672
+ versions: z3.array(z3.string()),
4673
+ affectedCount: z3.number().int(),
4674
+ nonAffectingCount: z3.number().int(),
4675
+ totalCount: z3.number().int(),
4676
+ maxSeverityScore: z3.number().nullable().optional(),
4677
+ maxSeverityLabel: z3.string().nullable().optional(),
4678
+ advisoryIds: z3.array(z3.string()),
4679
+ mostCritical: vulnerabilitySummaryDetailSchema.nullable().optional(),
4680
+ advisoryOccurrences: z3.array(transitiveDependencyVulnerabilitySchema).nullable().optional()
4681
+ });
4682
+ var transitiveVulnerabilitySummarySchema = z3.object({
4683
+ affected: vulnerabilityCountSummarySchema,
4684
+ nonAffecting: vulnerabilityCountSummarySchema,
4685
+ combined: vulnerabilityCountSummarySchema,
4686
+ totalPackagesAnalyzed: z3.number().int(),
4687
+ affectedPackageCount: z3.number().int(),
4688
+ packages: z3.array(transitiveVulnerablePackageSchema),
4689
+ calculatedAt: z3.string().nullable().optional()
4690
+ }).nullable().optional();
4691
+ var dependencyDeprecationReasonSchema = z3.object({
4692
+ version: z3.string(),
4693
+ reason: z3.string().nullable().optional()
4694
+ });
4695
+ var deprecatedDependencySchema = z3.object({
4696
+ registry: z3.string(),
4697
+ name: z3.string(),
4698
+ versions: z3.array(z3.string()),
4699
+ reasons: z3.array(dependencyDeprecationReasonSchema)
4700
+ });
4701
+ var outdatedDependencyVersionSchema = z3.object({
4702
+ version: z3.string(),
4703
+ severity: z3.string()
4704
+ });
4705
+ var outdatedDependencySchema = z3.object({
4706
+ registry: z3.string(),
4707
+ name: z3.string(),
4708
+ latestVersion: z3.string().nullable().optional(),
4709
+ severity: z3.string(),
4710
+ versions: z3.array(outdatedDependencyVersionSchema),
4711
+ repositoryUrl: z3.string().nullable().optional()
4712
+ });
4713
+ var duplicateDependencySchema = z3.object({
4714
+ registry: z3.string().nullable().optional(),
4715
+ name: z3.string(),
4716
+ versions: z3.array(z3.string())
4717
+ });
4294
4718
  var dependencyConflictEdgeSchema = z3.object({
4295
4719
  fromIndex: z3.number().int().nullable().optional(),
4296
4720
  toIndex: z3.number().int(),
@@ -4302,6 +4726,24 @@ var dependencyConflictSchema = z3.object({
4302
4726
  requiredVersions: z3.array(z3.string()),
4303
4727
  conflictingEdges: z3.array(dependencyConflictEdgeSchema)
4304
4728
  });
4729
+ var dependencyIssueConflictSchema = z3.object({
4730
+ registry: z3.string().nullable().optional(),
4731
+ name: z3.string(),
4732
+ versions: z3.array(z3.string()),
4733
+ requiredVersions: z3.array(z3.string()),
4734
+ conflictingEdges: z3.array(dependencyConflictEdgeSchema)
4735
+ });
4736
+ var dependencyIssuesSummarySchema = z3.object({
4737
+ totalCount: z3.number().int(),
4738
+ deprecatedCount: z3.number().int(),
4739
+ outdatedCount: z3.number().int(),
4740
+ duplicateCount: z3.number().int(),
4741
+ conflictCount: z3.number().int(),
4742
+ deprecatedPackages: z3.array(deprecatedDependencySchema),
4743
+ outdatedPackages: z3.array(outdatedDependencySchema),
4744
+ duplicatePackages: z3.array(duplicateDependencySchema),
4745
+ conflicts: z3.array(dependencyIssueConflictSchema)
4746
+ }).nullable().optional();
4305
4747
  var circularDependencyCycleSchema = z3.object({
4306
4748
  cycleStart: z3.string(),
4307
4749
  circularPath: z3.array(z3.string()),
@@ -4318,7 +4760,9 @@ var transitiveDependencySchema = z3.object({
4318
4760
  uniqueDependencies: z3.array(z3.string()).nullable().optional(),
4319
4761
  dependencyConflicts: z3.array(dependencyConflictSchema).nullable().optional(),
4320
4762
  circularDependencyCycles: z3.array(circularDependencyCycleSchema).nullable().optional(),
4321
- dependencyGraph: dependencyGraphSchema.nullable().optional()
4763
+ dependencyGraph: dependencyGraphSchema.nullable().optional(),
4764
+ vulnerabilitySummary: transitiveVulnerabilitySummarySchema,
4765
+ dependencyIssues: dependencyIssuesSummarySchema
4322
4766
  }).nullable().optional();
4323
4767
  var dependencyBundleSchema = z3.object({
4324
4768
  direct: z3.array(directDependencySchema).nullable().optional(),
@@ -4448,6 +4892,203 @@ query PackageDependencies(
4448
4892
  }
4449
4893
  }
4450
4894
  }`;
4895
+ var PACKAGE_UPGRADE_DEPENDENCY_PROBE_QUERY = `
4896
+ query PackageUpgradeDependencyProbe(
4897
+ $registry: Registry!
4898
+ $name: String!
4899
+ $version: String!
4900
+ $includeTransitiveRisk: Boolean!
4901
+ $includeTransitiveSecurity: Boolean!
4902
+ $includeDependencyIssues: Boolean!
4903
+ $includeDependencyChanges: Boolean!
4904
+ $includeGroups: Boolean!
4905
+ $lifecycle: [String!]
4906
+ $minSeverity: Float
4907
+ ) {
4908
+ packageDependencies(
4909
+ registry: $registry
4910
+ name: $name
4911
+ version: $version
4912
+ includeTransitive: $includeTransitiveRisk
4913
+ lifecycle: $lifecycle
4914
+ ) {
4915
+ package {
4916
+ name
4917
+ registry
4918
+ version
4919
+ publishedAt
4920
+ deprecated
4921
+ deprecationReason
4922
+ }
4923
+ dependencies {
4924
+ direct {
4925
+ name
4926
+ versionConstraint
4927
+ type
4928
+ }
4929
+ transitive @include(if: $includeTransitiveRisk) {
4930
+ dependencyGraph @include(if: $includeDependencyChanges) {
4931
+ formatVersion
4932
+ nodes {
4933
+ registry
4934
+ name
4935
+ version
4936
+ }
4937
+ edges {
4938
+ fromIndex
4939
+ toIndex
4940
+ constraint
4941
+ dependencyType
4942
+ }
4943
+ }
4944
+ vulnerabilitySummary(minSeverity: $minSeverity) @include(if: $includeTransitiveSecurity) {
4945
+ affected {
4946
+ totalVulnerabilities
4947
+ critical
4948
+ high
4949
+ medium
4950
+ low
4951
+ unknown
4952
+ }
4953
+ nonAffecting {
4954
+ totalVulnerabilities
4955
+ critical
4956
+ high
4957
+ medium
4958
+ low
4959
+ unknown
4960
+ }
4961
+ combined {
4962
+ totalVulnerabilities
4963
+ critical
4964
+ high
4965
+ medium
4966
+ low
4967
+ unknown
4968
+ }
4969
+ totalPackagesAnalyzed
4970
+ affectedPackageCount
4971
+ calculatedAt
4972
+ packages {
4973
+ registry
4974
+ name
4975
+ versions
4976
+ affectedCount
4977
+ nonAffectingCount
4978
+ totalCount
4979
+ maxSeverityScore
4980
+ maxSeverityLabel
4981
+ advisoryIds(scope: AFFECTED)
4982
+ mostCritical {
4983
+ osvId
4984
+ registry
4985
+ packageName
4986
+ summary
4987
+ severityScore
4988
+ severityType
4989
+ affectedVersionRanges
4990
+ fixedInVersions
4991
+ publishedAt
4992
+ modifiedAt
4993
+ withdrawnAt
4994
+ aliases
4995
+ isMalicious
4996
+ }
4997
+ advisoryOccurrences(scope: AFFECTED, minSeverity: $minSeverity, limit: 5) {
4998
+ version
4999
+ affectsResolvedVersion
5000
+ matchedAffectedVersionRanges
5001
+ fixVersionsAboveResolved
5002
+ nearestFixedVersion
5003
+ advisory {
5004
+ osvId
5005
+ registry
5006
+ packageName
5007
+ summary
5008
+ severityScore
5009
+ severityType
5010
+ affectedVersionRanges
5011
+ fixedInVersions
5012
+ publishedAt
5013
+ modifiedAt
5014
+ withdrawnAt
5015
+ aliases
5016
+ isMalicious
5017
+ }
5018
+ }
5019
+ }
5020
+ }
5021
+ dependencyIssues @include(if: $includeDependencyIssues) {
5022
+ totalCount
5023
+ deprecatedCount
5024
+ outdatedCount
5025
+ duplicateCount
5026
+ conflictCount
5027
+ deprecatedPackages {
5028
+ registry
5029
+ name
5030
+ versions
5031
+ reasons {
5032
+ version
5033
+ reason
5034
+ }
5035
+ }
5036
+ outdatedPackages {
5037
+ registry
5038
+ name
5039
+ latestVersion
5040
+ severity
5041
+ versions {
5042
+ version
5043
+ severity
5044
+ }
5045
+ repositoryUrl
5046
+ }
5047
+ duplicatePackages {
5048
+ registry
5049
+ name
5050
+ versions
5051
+ }
5052
+ conflicts {
5053
+ registry
5054
+ name
5055
+ versions
5056
+ requiredVersions
5057
+ conflictingEdges {
5058
+ fromIndex
5059
+ toIndex
5060
+ versionConstraint
5061
+ dependencyType
5062
+ }
5063
+ }
5064
+ }
5065
+ }
5066
+ }
5067
+ dependencyGroups @include(if: $includeGroups) {
5068
+ primaryGroup
5069
+ environmentMarkers {
5070
+ type
5071
+ value
5072
+ raw
5073
+ }
5074
+ groups {
5075
+ name
5076
+ lifecycle
5077
+ conditionType
5078
+ conditionValue
5079
+ selectionMode
5080
+ exclusiveGroup
5081
+ fallbackPriority
5082
+ compatibleWith
5083
+ defaultEnabled
5084
+ dependencies {
5085
+ name
5086
+ constraint
5087
+ }
5088
+ }
5089
+ }
5090
+ }
5091
+ }`;
4451
5092
  var changelogPackageInfoSchema = z3.object({
4452
5093
  name: z3.string().nullable().optional(),
4453
5094
  registry: z3.string().nullable().optional(),
@@ -4915,7 +5556,10 @@ class PackageIntelligenceServiceImpl {
4915
5556
  const identity = {
4916
5557
  name,
4917
5558
  version: version2,
4918
- registry: data.package?.registry ?? undefined
5559
+ registry: data.package?.registry ?? undefined,
5560
+ publishedAt: data.package?.publishedAt ?? undefined,
5561
+ deprecated: data.package?.deprecated ?? undefined,
5562
+ deprecationReason: data.package?.deprecationReason ?? undefined
4919
5563
  };
4920
5564
  const security = data.security ? {
4921
5565
  affectedVulnerabilityCount: data.security.affectedVulnerabilityCount,
@@ -4955,6 +5599,58 @@ class PackageIntelligenceServiceImpl {
4955
5599
  executeWithToken: (token) => this.executePackageDependencies(token, params)
4956
5600
  }));
4957
5601
  }
5602
+ async packageUpgradeDependencyProbe(params) {
5603
+ return withTelemetrySpan("pkg-intel.upgrade-dependency-probe.request", () => executeWithTokenRefresh({
5604
+ getToken: () => this.tokenProvider.getToken(),
5605
+ forceRefresh: () => this.tokenProvider.forceRefresh(),
5606
+ shouldRefresh: (error) => error instanceof AuthenticationError,
5607
+ executeWithToken: (token) => this.executePackageUpgradeDependencyProbe(token, params)
5608
+ }));
5609
+ }
5610
+ async executePackageUpgradeDependencyProbe(token, params) {
5611
+ const includeTransitiveRisk = params.includeTransitiveSecurity === true || params.includeDependencyIssues === true || params.includeDependencyChanges === true;
5612
+ let response;
5613
+ try {
5614
+ response = await postPkgseerGraphql({
5615
+ endpointUrl: this.endpointUrl,
5616
+ token,
5617
+ query: PACKAGE_UPGRADE_DEPENDENCY_PROBE_QUERY,
5618
+ variables: {
5619
+ registry: params.registry,
5620
+ name: params.packageName,
5621
+ version: params.version,
5622
+ includeTransitiveRisk,
5623
+ includeTransitiveSecurity: params.includeTransitiveSecurity === true,
5624
+ includeDependencyIssues: params.includeDependencyIssues === true,
5625
+ includeDependencyChanges: params.includeDependencyChanges === true,
5626
+ includeGroups: params.includeGroups === true,
5627
+ lifecycle: params.includeGroups === true ? ["peer"] : undefined,
5628
+ minSeverity: params.minSeverity
5629
+ },
5630
+ fetchFn: this.fetchFn
5631
+ });
5632
+ } catch (cause) {
5633
+ if (cause instanceof PkgseerTransportError) {
5634
+ throw new PackageIntelligenceNetworkError("Could not reach the package intelligence service. Check your connection or set GITHITS_CODE_NAV_URL.", { cause });
5635
+ }
5636
+ throw cause;
5637
+ }
5638
+ if (response.status < 200 || response.status >= 300) {
5639
+ throw this.createHttpError(response);
5640
+ }
5641
+ const parsed = dependenciesGraphQLResponseSchema.safeParse(response.parsedBody);
5642
+ if (!parsed.success) {
5643
+ throw new MalformedPackageIntelligenceResponseError("Malformed response from the package-intelligence service.");
5644
+ }
5645
+ if (parsed.data.errors && parsed.data.errors.length > 0) {
5646
+ throw promoteGenericVersionNotFound(this.createGraphQLError(parsed.data.errors), params);
5647
+ }
5648
+ const data = parsed.data.data?.packageDependencies;
5649
+ if (!data) {
5650
+ throw new MalformedPackageIntelligenceResponseError("Empty response from the package-intelligence service.");
5651
+ }
5652
+ return this.normaliseDependencyReport(data);
5653
+ }
4958
5654
  async executePackageDependencies(token, params) {
4959
5655
  let response;
4960
5656
  try {
@@ -5003,7 +5699,10 @@ class PackageIntelligenceServiceImpl {
5003
5699
  const identity = {
5004
5700
  name,
5005
5701
  version: version2,
5006
- registry: data.package?.registry ?? undefined
5702
+ registry: data.package?.registry ?? undefined,
5703
+ publishedAt: data.package?.publishedAt ?? undefined,
5704
+ deprecated: data.package?.deprecated ?? undefined,
5705
+ deprecationReason: data.package?.deprecationReason ?? undefined
5007
5706
  };
5008
5707
  const bundle = data.dependencies;
5009
5708
  const dependencies = bundle ? {
@@ -5049,7 +5748,9 @@ class PackageIntelligenceServiceImpl {
5049
5748
  constraint: e.constraint ?? undefined,
5050
5749
  dependencyType: e.dependencyType ?? undefined
5051
5750
  }))
5052
- } : undefined
5751
+ } : undefined,
5752
+ vulnerabilitySummary: this.normaliseTransitiveVulnerabilitySummary(bundle.transitive.vulnerabilitySummary),
5753
+ dependencyIssues: this.normaliseDependencyIssuesSummary(bundle.transitive.dependencyIssues)
5053
5754
  } : undefined
5054
5755
  } : undefined;
5055
5756
  const dependencyGroups = data.dependencyGroups ? {
@@ -5081,6 +5782,103 @@ class PackageIntelligenceServiceImpl {
5081
5782
  dependencyGroups
5082
5783
  };
5083
5784
  }
5785
+ normaliseTransitiveVulnerabilitySummary(summary) {
5786
+ if (!summary)
5787
+ return;
5788
+ return {
5789
+ affected: summary.affected,
5790
+ nonAffecting: summary.nonAffecting,
5791
+ combined: summary.combined,
5792
+ totalPackagesAnalyzed: summary.totalPackagesAnalyzed,
5793
+ affectedPackageCount: summary.affectedPackageCount,
5794
+ calculatedAt: summary.calculatedAt ?? undefined,
5795
+ packages: summary.packages.map((pkg) => ({
5796
+ registry: pkg.registry,
5797
+ name: pkg.name,
5798
+ versions: pkg.versions,
5799
+ affectedCount: pkg.affectedCount,
5800
+ nonAffectingCount: pkg.nonAffectingCount,
5801
+ totalCount: pkg.totalCount,
5802
+ maxSeverityScore: pkg.maxSeverityScore ?? undefined,
5803
+ maxSeverityLabel: pkg.maxSeverityLabel ?? undefined,
5804
+ advisoryIds: pkg.advisoryIds,
5805
+ mostCritical: pkg.mostCritical ? this.normaliseVulnerabilitySummaryDetail(pkg.mostCritical) : undefined,
5806
+ advisoryOccurrences: pkg.advisoryOccurrences?.map((occurrence) => ({
5807
+ version: occurrence.version,
5808
+ affectsResolvedVersion: occurrence.affectsResolvedVersion,
5809
+ matchedAffectedVersionRanges: occurrence.matchedAffectedVersionRanges,
5810
+ fixVersionsAboveResolved: occurrence.fixVersionsAboveResolved,
5811
+ nearestFixedVersion: occurrence.nearestFixedVersion ?? undefined,
5812
+ advisory: this.normaliseVulnerabilitySummaryDetail(occurrence.advisory)
5813
+ })) ?? undefined
5814
+ }))
5815
+ };
5816
+ }
5817
+ normaliseVulnerabilitySummaryDetail(advisory) {
5818
+ return {
5819
+ osvId: advisory.osvId ?? undefined,
5820
+ registry: advisory.registry ?? undefined,
5821
+ packageName: advisory.packageName ?? undefined,
5822
+ summary: advisory.summary ?? undefined,
5823
+ severityScore: advisory.severityScore ?? undefined,
5824
+ severityType: advisory.severityType ?? undefined,
5825
+ affectedVersionRanges: advisory.affectedVersionRanges ?? undefined,
5826
+ fixedInVersions: advisory.fixedInVersions ?? undefined,
5827
+ publishedAt: advisory.publishedAt ?? undefined,
5828
+ modifiedAt: advisory.modifiedAt ?? undefined,
5829
+ withdrawnAt: advisory.withdrawnAt ?? undefined,
5830
+ aliases: advisory.aliases ?? undefined,
5831
+ isMalicious: advisory.isMalicious ?? undefined
5832
+ };
5833
+ }
5834
+ normaliseDependencyIssuesSummary(issues) {
5835
+ if (!issues)
5836
+ return;
5837
+ return {
5838
+ totalCount: issues.totalCount,
5839
+ deprecatedCount: issues.deprecatedCount,
5840
+ outdatedCount: issues.outdatedCount,
5841
+ duplicateCount: issues.duplicateCount,
5842
+ conflictCount: issues.conflictCount,
5843
+ deprecatedPackages: issues.deprecatedPackages.map((pkg) => ({
5844
+ registry: pkg.registry,
5845
+ name: pkg.name,
5846
+ versions: pkg.versions,
5847
+ reasons: pkg.reasons.map((reason) => ({
5848
+ version: reason.version,
5849
+ reason: reason.reason ?? undefined
5850
+ }))
5851
+ })),
5852
+ outdatedPackages: issues.outdatedPackages.map((pkg) => ({
5853
+ registry: pkg.registry,
5854
+ name: pkg.name,
5855
+ latestVersion: pkg.latestVersion ?? undefined,
5856
+ severity: pkg.severity,
5857
+ versions: pkg.versions.map((version2) => ({
5858
+ version: version2.version,
5859
+ severity: version2.severity
5860
+ })),
5861
+ repositoryUrl: pkg.repositoryUrl ?? undefined
5862
+ })),
5863
+ duplicatePackages: issues.duplicatePackages.map((pkg) => ({
5864
+ registry: pkg.registry ?? undefined,
5865
+ name: pkg.name,
5866
+ versions: pkg.versions
5867
+ })),
5868
+ conflicts: issues.conflicts.map((conflict) => ({
5869
+ registry: conflict.registry ?? undefined,
5870
+ name: conflict.name,
5871
+ versions: conflict.versions,
5872
+ requiredVersions: conflict.requiredVersions,
5873
+ conflictingEdges: conflict.conflictingEdges.map((edge) => ({
5874
+ fromIndex: edge.fromIndex ?? undefined,
5875
+ toIndex: edge.toIndex,
5876
+ versionConstraint: edge.versionConstraint,
5877
+ dependencyType: edge.dependencyType
5878
+ }))
5879
+ }))
5880
+ };
5881
+ }
5084
5882
  async packageChangelog(params) {
5085
5883
  return withTelemetrySpan("pkg-intel.changelog.request", () => executeWithTokenRefresh({
5086
5884
  getToken: () => this.tokenProvider.getToken(),