@codingame/monaco-vscode-issue-service-override 37.6.1 → 38.0.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codingame/monaco-vscode-issue-service-override",
3
- "version": "37.6.1",
3
+ "version": "38.0.0",
4
4
  "private": false,
5
5
  "description": "VSCode public API plugged on the monaco editor - issue service-override",
6
6
  "keywords": [],
@@ -15,7 +15,7 @@
15
15
  },
16
16
  "type": "module",
17
17
  "dependencies": {
18
- "@codingame/monaco-vscode-api": "37.6.1"
18
+ "@codingame/monaco-vscode-api": "38.0.0"
19
19
  },
20
20
  "main": "index.js",
21
21
  "module": "index.js",
@@ -4,6 +4,7 @@ import { Disposable } from "@codingame/monaco-vscode-api/vscode/vs/base/common/l
4
4
  import { IProductConfiguration } from "@codingame/monaco-vscode-api/vscode/vs/base/common/product";
5
5
  import { IFileDialogService } from "@codingame/monaco-vscode-api/vscode/vs/platform/dialogs/common/dialogs.service";
6
6
  import { IFileService } from "@codingame/monaco-vscode-api/vscode/vs/platform/files/common/files.service";
7
+ import { ILogService } from "@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service";
7
8
  import { IOpenerService } from "@codingame/monaco-vscode-api/vscode/vs/platform/opener/common/opener.service";
8
9
  import { IThemeService } from "@codingame/monaco-vscode-api/vscode/vs/platform/theme/common/themeService.service";
9
10
  import { IContextMenuService } from "@codingame/monaco-vscode-api/vscode/vs/platform/contextview/browser/contextView.service";
@@ -22,6 +23,7 @@ export declare class BaseIssueReporterService extends Disposable {
22
23
  product: IProductConfiguration;
23
24
  readonly window: Window;
24
25
  readonly isWeb: boolean;
26
+ private readonly fetcher;
25
27
  readonly issueFormService: IIssueFormService;
26
28
  readonly themeService: IThemeService;
27
29
  readonly fileService: IFileService;
@@ -29,6 +31,7 @@ export declare class BaseIssueReporterService extends Disposable {
29
31
  readonly contextMenuService: IContextMenuService;
30
32
  readonly authenticationService: IAuthenticationService;
31
33
  readonly openerService: IOpenerService;
34
+ private readonly logService;
32
35
  issueReporterModel: IssueReporterModel;
33
36
  receivedSystemInfo: boolean;
34
37
  numberOfSearchResultsDisplayed: number;
@@ -47,11 +50,13 @@ export declare class BaseIssueReporterService extends Disposable {
47
50
  private createAction;
48
51
  private previewAction;
49
52
  private privateAction;
53
+ private readonly similarIssueSearch;
54
+ private similarIssueSearchGeneration;
50
55
  constructor(disableExtensions: boolean, data: IssueReporterData, os: {
51
56
  type: string;
52
57
  arch: string;
53
58
  release: string;
54
- }, product: IProductConfiguration, window: Window, isWeb: boolean, issueFormService: IIssueFormService, themeService: IThemeService, fileService: IFileService, fileDialogService: IFileDialogService, contextMenuService: IContextMenuService, authenticationService: IAuthenticationService, openerService: IOpenerService);
59
+ }, product: IProductConfiguration, window: Window, isWeb: boolean, fetcher: typeof fetch | undefined, issueFormService: IIssueFormService, themeService: IThemeService, fileService: IFileService, fileDialogService: IFileDialogService, contextMenuService: IContextMenuService, authenticationService: IAuthenticationService, openerService: IOpenerService, logService: ILogService);
55
60
  render(): void;
56
61
  setInitialFocus(): void;
57
62
  updateButtonStates(): void;
@@ -10,7 +10,7 @@ import { Codicon } from '@codingame/monaco-vscode-api/vscode/vs/base/common/codi
10
10
  import { groupBy } from '@codingame/monaco-vscode-api/vscode/vs/base/common/collections';
11
11
  import { debounce } from '@codingame/monaco-vscode-api/vscode/vs/base/common/decorators';
12
12
  import { CancellationError } from '@codingame/monaco-vscode-api/vscode/vs/base/common/errors';
13
- import { Disposable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
13
+ import { Disposable, MutableDisposable, toDisposable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
14
14
  import { Schemas } from '@codingame/monaco-vscode-api/vscode/vs/base/common/network';
15
15
  import { isLinuxSnap, isMacintosh } from '@codingame/monaco-vscode-api/vscode/vs/base/common/platform';
16
16
  import { joinPath } from '@codingame/monaco-vscode-api/vscode/vs/base/common/resources';
@@ -21,6 +21,7 @@ import { Action } from '@codingame/monaco-vscode-api/vscode/vs/base/common/actio
21
21
  import { localize } from '@codingame/monaco-vscode-api/vscode/vs/nls';
22
22
  import { IFileDialogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/dialogs/common/dialogs.service';
23
23
  import { IFileService } from '@codingame/monaco-vscode-api/vscode/vs/platform/files/common/files.service';
24
+ import { ILogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service';
24
25
  import { IOpenerService } from '@codingame/monaco-vscode-api/vscode/vs/platform/opener/common/opener.service';
25
26
  import { getIconsStyleSheet } from '@codingame/monaco-vscode-api/vscode/vs/platform/theme/browser/iconsStyleSheet';
26
27
  import { IThemeService } from '@codingame/monaco-vscode-api/vscode/vs/platform/theme/common/themeService.service';
@@ -48,13 +49,15 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
48
49
  product,
49
50
  window,
50
51
  isWeb,
52
+ fetcher = (input, init) => fetch(input, init),
51
53
  issueFormService,
52
54
  themeService,
53
55
  fileService,
54
56
  fileDialogService,
55
57
  contextMenuService,
56
58
  authenticationService,
57
- openerService
59
+ openerService,
60
+ logService
58
61
  ) {
59
62
  super();
60
63
  this.disableExtensions = disableExtensions;
@@ -63,6 +66,7 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
63
66
  this.product = product;
64
67
  this.window = window;
65
68
  this.isWeb = isWeb;
69
+ this.fetcher = fetcher;
66
70
  this.issueFormService = issueFormService;
67
71
  this.themeService = themeService;
68
72
  this.fileService = fileService;
@@ -70,6 +74,7 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
70
74
  this.contextMenuService = contextMenuService;
71
75
  this.authenticationService = authenticationService;
72
76
  this.openerService = openerService;
77
+ this.logService = logService;
73
78
  this.receivedSystemInfo = false;
74
79
  this.numberOfSearchResultsDisplayed = 0;
75
80
  this.receivedPerformanceInfo = false;
@@ -82,10 +87,12 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
82
87
  this.nonGitHubIssueUrl = false;
83
88
  this.needsUpdate = false;
84
89
  this.acknowledged = false;
90
+ this.similarIssueSearch = this._register(( new MutableDisposable()));
91
+ this.similarIssueSearchGeneration = 0;
85
92
  const targetExtension = data.extensionId ? data.enabledExtensions.find(
86
93
  extension => extension.id.toLocaleLowerCase() === data.extensionId?.toLocaleLowerCase()
87
94
  ) : undefined;
88
- this.issueReporterModel = ( new IssueReporterModel({
95
+ this.issueReporterModel = this._register(( new IssueReporterModel({
89
96
  ...data,
90
97
  issueType: data.issueType || IssueType.Bug,
91
98
  versionInfo: {
@@ -95,7 +102,7 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
95
102
  extensionsDisabled: !!this.disableExtensions,
96
103
  fileOnExtension: data.extensionId ? !targetExtension?.isBuiltin : undefined,
97
104
  selectedExtension: targetExtension
98
- }));
105
+ })));
99
106
  this._register(this.authenticationService.onDidChangeSessions(async () => {
100
107
  const previousAuthState = !!this.data.githubAccessToken;
101
108
  let githubAccessToken = "";
@@ -116,7 +123,7 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
116
123
  fileOnMarketplace,
117
124
  fileOnProduct
118
125
  });
119
- this.createAction = this._register(( new Action("issueReporter.create", ( localize(15621, "Create on GitHub")), undefined, true, async () => {
126
+ this.createAction = this._register(( new Action("issueReporter.create", ( localize(18035, "Create on GitHub")), undefined, true, async () => {
120
127
  this.delayedSubmit.trigger(async () => {
121
128
  this.setSubmittingState(true);
122
129
  try {
@@ -126,7 +133,7 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
126
133
  }
127
134
  });
128
135
  })));
129
- this.previewAction = this._register(( new Action("issueReporter.preview", ( localize(15622, "Preview on GitHub")), undefined, true, async () => {
136
+ this.previewAction = this._register(( new Action("issueReporter.preview", ( localize(18036, "Preview on GitHub")), undefined, true, async () => {
130
137
  this.delayedSubmit.trigger(async () => {
131
138
  this.setSubmittingState(true);
132
139
  try {
@@ -136,7 +143,7 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
136
143
  }
137
144
  });
138
145
  })));
139
- this.privateAction = this._register(( new Action("issueReporter.privateCreate", ( localize(15623, "Create Internally")), undefined, true, async () => {
146
+ this.privateAction = this._register(( new Action("issueReporter.privateCreate", ( localize(18037, "Create Internally")), undefined, true, async () => {
140
147
  this.delayedSubmit.trigger(async () => {
141
148
  this.setSubmittingState(true);
142
149
  try {
@@ -241,7 +248,7 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
241
248
  filingNote.classList.add("internal-preview-message");
242
249
  container.appendChild(filingNote);
243
250
  }
244
- filingNote.textContent = escape(( localize(15624, "If your copilot debug logs contain private information:")));
251
+ filingNote.textContent = escape(( localize(18038, "If your copilot debug logs contain private information:")));
245
252
  }
246
253
  updatePublicGithubButton(container) {
247
254
  const issueReporterElement = this.getElementById("issue-reporter");
@@ -253,7 +260,7 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
253
260
  }
254
261
  if (!this.acknowledged && this.needsUpdate) {
255
262
  this.publicGithubButton = this._register(( new Button(container, unthemedButtonStyles)));
256
- this.publicGithubButton.label = ( localize(15625, "Confirm Version Acknowledgement"));
263
+ this.publicGithubButton.label = ( localize(18039, "Confirm Version Acknowledgement"));
257
264
  this.publicGithubButton.enabled = false;
258
265
  } else if (this.data.githubAccessToken && this.isPreviewEnabled()) {
259
266
  this.publicGithubButton = this._register(( new ButtonWithDropdown(container, {
@@ -265,21 +272,21 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
265
272
  this._register(this.publicGithubButton.onDidClick(() => {
266
273
  this.createAction.run();
267
274
  }));
268
- this.publicGithubButton.label = ( localize(15626, "Create on GitHub"));
275
+ this.publicGithubButton.label = ( localize(18040, "Create on GitHub"));
269
276
  this.publicGithubButton.enabled = true;
270
277
  } else if (this.data.githubAccessToken && !this.isPreviewEnabled()) {
271
278
  this.publicGithubButton = this._register(( new Button(container, unthemedButtonStyles)));
272
279
  this._register(this.publicGithubButton.onDidClick(() => {
273
280
  this.createAction.run();
274
281
  }));
275
- this.publicGithubButton.label = ( localize(15626, "Create on GitHub"));
282
+ this.publicGithubButton.label = ( localize(18040, "Create on GitHub"));
276
283
  this.publicGithubButton.enabled = true;
277
284
  } else {
278
285
  this.publicGithubButton = this._register(( new Button(container, unthemedButtonStyles)));
279
286
  this._register(this.publicGithubButton.onDidClick(() => {
280
287
  this.previewAction.run();
281
288
  }));
282
- this.publicGithubButton.label = ( localize(15627, "Preview on GitHub"));
289
+ this.publicGithubButton.label = ( localize(18041, "Preview on GitHub"));
283
290
  this.publicGithubButton.enabled = true;
284
291
  }
285
292
  const repoLink = this.getElementById("show-repo-name");
@@ -332,7 +339,7 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
332
339
  }));
333
340
  this.internalGithubButton.element.id = "internal-create-btn";
334
341
  this.internalGithubButton.element.classList.add("internal-create-subtle");
335
- this.internalGithubButton.label = ( localize(15628, "Create Internally"));
342
+ this.internalGithubButton.label = ( localize(18042, "Create Internally"));
336
343
  this.internalGithubButton.enabled = true;
337
344
  this.internalGithubButton.setTitle(this.data.privateUri.path.slice(1));
338
345
  }
@@ -368,7 +375,7 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
368
375
  if (submitting) {
369
376
  const currentLabel = this.publicGithubButton instanceof ButtonWithDropdown ? this.publicGithubButton.primaryButton.label : this.publicGithubButton.label;
370
377
  this.preSubmitButtonLabel = typeof currentLabel === "string" ? currentLabel : "";
371
- this.publicGithubButton.label = ( localize(15629, "Submitting..."));
378
+ this.publicGithubButton.label = ( localize(18043, "Submitting..."));
372
379
  const spinnerIcon = renderIcon(ThemeIcon.modify(Codicon.loading, "spin"));
373
380
  buttonEl.prepend(spinnerIcon);
374
381
  } else {
@@ -440,7 +447,7 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
440
447
  const {
441
448
  selectedExtension
442
449
  } = this.issueReporterModel.getData();
443
- reset(extensionsSelector, this.makeOption("", ( localize(15630, "Select extension")), true), ...extensionOptions.map(extension => makeOption(extension, selectedExtension)));
450
+ reset(extensionsSelector, this.makeOption("", ( localize(18044, "Select extension")), true), ...extensionOptions.map(extension => makeOption(extension, selectedExtension)));
444
451
  if (!selectedExtension) {
445
452
  extensionsSelector.selectedIndex = 0;
446
453
  }
@@ -544,10 +551,10 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
544
551
  const info = containingElement && containingElement.lastElementChild;
545
552
  if (info && info.classList.contains("hidden")) {
546
553
  show(info);
547
- label.textContent = ( localize(15631, "hide"));
554
+ label.textContent = ( localize(18045, "hide"));
548
555
  } else {
549
556
  hide(info);
550
- label.textContent = ( localize(15632, "show"));
557
+ label.textContent = ( localize(18046, "show"));
551
558
  }
552
559
  }
553
560
  });
@@ -568,13 +575,13 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
568
575
  }
569
576
  const descriptionTextArea = this.getElementById("issue-title");
570
577
  if (value === IssueSource.VSCode) {
571
- descriptionTextArea.placeholder = ( localize(15633, "E.g Workbench is missing problems panel"));
578
+ descriptionTextArea.placeholder = ( localize(18047, "E.g Workbench is missing problems panel"));
572
579
  } else if (value === IssueSource.Extension) {
573
- descriptionTextArea.placeholder = ( localize(15634, "E.g. Missing alt text on extension readme image"));
580
+ descriptionTextArea.placeholder = ( localize(18048, "E.g. Missing alt text on extension readme image"));
574
581
  } else if (value === IssueSource.Marketplace) {
575
- descriptionTextArea.placeholder = ( localize(15635, "E.g Cannot disable installed extension"));
582
+ descriptionTextArea.placeholder = ( localize(18049, "E.g Cannot disable installed extension"));
576
583
  } else {
577
- descriptionTextArea.placeholder = ( localize(15636, "Please enter a title"));
584
+ descriptionTextArea.placeholder = ( localize(18050, "Please enter a title"));
578
585
  }
579
586
  let fileOnExtension, fileOnMarketplace, fileOnProduct = false;
580
587
  if (value === IssueSource.Extension) {
@@ -598,7 +605,7 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
598
605
  this.issueReporterModel.update({
599
606
  issueDescription
600
607
  });
601
- if (this.issueReporterModel.fileOnExtension() === false) {
608
+ if (this.issueReporterModel.fileOnExtension() === false && !this.issueReporterModel.getData().fileOnMarketplace) {
602
609
  const title = this.getElementById("issue-title").value;
603
610
  this.searchVSCodeIssues(title, issueDescription);
604
611
  }
@@ -725,13 +732,16 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
725
732
  return selectedExtension && selectedExtension.bugsUrl;
726
733
  }
727
734
  searchVSCodeIssues(title, issueDescription) {
735
+ this.clearSearchResults();
728
736
  if (title) {
729
- this.searchDuplicates(title, issueDescription);
730
- } else {
731
- this.clearSearchResults();
737
+ this.searchDuplicates(title, issueDescription, this.similarIssueSearchGeneration);
732
738
  }
733
739
  }
734
740
  searchIssues(title, fileOnExtension, fileOnMarketplace) {
741
+ this.clearSearchResults();
742
+ if (!title) {
743
+ return;
744
+ }
735
745
  if (fileOnExtension) {
736
746
  return this.searchExtensionIssues(title);
737
747
  }
@@ -739,7 +749,7 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
739
749
  return this.searchMarketplaceIssues(title);
740
750
  }
741
751
  const description = this.issueReporterModel.getData().issueDescription;
742
- this.searchVSCodeIssues(title, description);
752
+ this.searchDuplicates(title, description, this.similarIssueSearchGeneration);
743
753
  }
744
754
  searchExtensionIssues(title) {
745
755
  const url = this.getExtensionGitHubUrl();
@@ -747,7 +757,7 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
747
757
  const matches = /^https?:\/\/github\.com\/(.*)/.exec(url);
748
758
  if (matches && matches.length) {
749
759
  const repo = matches[1];
750
- return this.searchGitHub(repo, title);
760
+ return this.searchGitHub(repo, title, this.similarIssueSearchGeneration);
751
761
  }
752
762
  if (this.issueReporterModel.getData().selectedExtension) {
753
763
  this.clearSearchResults();
@@ -760,7 +770,11 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
760
770
  if (title) {
761
771
  const gitHubInfo = this.parseGitHubUrl(this.product.reportMarketplaceIssueUrl);
762
772
  if (gitHubInfo) {
763
- return this.searchGitHub(`${gitHubInfo.owner}/${gitHubInfo.repositoryName}`, title);
773
+ return this.searchGitHub(
774
+ `${gitHubInfo.owner}/${gitHubInfo.repositoryName}`,
775
+ title,
776
+ this.similarIssueSearchGeneration
777
+ );
764
778
  }
765
779
  }
766
780
  }
@@ -768,27 +782,36 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
768
782
  await this.issueFormService.closeReporter();
769
783
  }
770
784
  clearSearchResults() {
785
+ this.similarIssueSearchGeneration++;
786
+ this.similarIssueSearch.clear();
771
787
  const similarIssues = this.getElementById("similar-issues");
772
788
  similarIssues.innerText = "";
773
789
  this.numberOfSearchResultsDisplayed = 0;
774
790
  }
775
- searchGitHub(repo, title) {
776
- const query = `is:issue+repo:${repo}+${title}`;
791
+ searchGitHub(repo, title, generation) {
792
+ if (this._store.isDisposed || generation !== this.similarIssueSearchGeneration) {
793
+ return;
794
+ }
795
+ const controller = ( new AbortController());
796
+ this.similarIssueSearch.value = toDisposable(() => controller.abort());
777
797
  const similarIssues = this.getElementById("similar-issues");
778
- fetch(`https://api.github.com/search/issues?q=${query}`).then(response => {
779
- response.json().then(result => {
798
+ void this.issueFormService.searchGitHubIssues(repo, title, controller.signal).then(results => {
799
+ if (!controller.signal.aborted) {
780
800
  similarIssues.innerText = "";
781
- if (result && result.items) {
782
- this.displaySearchResults(result.items);
783
- }
784
- }).catch(_ => {
785
- console.warn("Timeout or query limit exceeded");
786
- });
787
- }).catch(_ => {
788
- console.warn("Error fetching GitHub issues");
801
+ this.displaySearchResults(results);
802
+ }
803
+ }).catch(error => {
804
+ if (!controller.signal.aborted) {
805
+ this.logService.warn("[IssueReporter] Error fetching GitHub issues", error);
806
+ }
789
807
  });
790
808
  }
791
- searchDuplicates(title, body) {
809
+ searchDuplicates(title, body, generation) {
810
+ if (this._store.isDisposed || generation !== this.similarIssueSearchGeneration) {
811
+ return;
812
+ }
813
+ const controller = ( new AbortController());
814
+ this.similarIssueSearch.value = toDisposable(() => controller.abort());
792
815
  const url = "https://vscode-probot.westus.cloudapp.azure.com:7890/duplicate_candidates";
793
816
  const init = {
794
817
  method: "POST",
@@ -798,25 +821,30 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
798
821
  }),
799
822
  headers: ( new Headers({
800
823
  "Content-Type": "application/json"
801
- }))
824
+ })),
825
+ signal: controller.signal
802
826
  };
803
- fetch(url, init).then(response => {
804
- response.json().then(result => {
805
- this.clearSearchResults();
806
- if (result && result.candidates) {
807
- this.displaySearchResults(result.candidates);
808
- } else {
809
- throw ( new Error("Unexpected response, no candidates property"));
810
- }
811
- }).catch(_ => {});
812
- }).catch(_ => {});
827
+ void this.fetcher(url, init).then(async response => {
828
+ const result = await response.json();
829
+ if (controller.signal.aborted) {
830
+ return;
831
+ }
832
+ if (!result || !Array.isArray(result.candidates)) {
833
+ throw ( new Error("Unexpected response, no candidates property"));
834
+ }
835
+ this.displaySearchResults(result.candidates);
836
+ }).catch(error => {
837
+ if (!controller.signal.aborted) {
838
+ this.logService.warn("[IssueReporter] Error fetching duplicate issues", error);
839
+ }
840
+ });
813
841
  }
814
842
  displaySearchResults(results) {
815
843
  const similarIssues = this.getElementById("similar-issues");
816
844
  if (results.length) {
817
845
  const issues = $("div.issues-container");
818
846
  const issuesText = $("div.list-title");
819
- issuesText.textContent = ( localize(15637, "Similar issues"));
847
+ issuesText.textContent = ( localize(18051, "Similar issues"));
820
848
  this.numberOfSearchResultsDisplayed = results.length < 5 ? results.length : 5;
821
849
  for (let i = 0; i < this.numberOfSearchResultsDisplayed; i++) {
822
850
  const issue = results[i];
@@ -836,8 +864,8 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
836
864
  renderIcon(issue.state === "open" ? Codicon.issueOpened : Codicon.issueClosed)
837
865
  );
838
866
  const issueStateLabel = $("span.issue-state.label");
839
- issueStateLabel.textContent = issue.state === "open" ? ( localize(15638, "Open")) : ( localize(15639, "Closed"));
840
- issueState.title = issue.state === "open" ? ( localize(15638, "Open")) : ( localize(15639, "Closed"));
867
+ issueStateLabel.textContent = issue.state === "open" ? ( localize(18052, "Open")) : ( localize(18053, "Closed"));
868
+ issueState.title = issue.state === "open" ? ( localize(18052, "Open")) : ( localize(18053, "Closed"));
841
869
  issueState.appendChild(issueIcon);
842
870
  issueState.appendChild(issueStateLabel);
843
871
  item = $("div.issue", undefined, issueState, link);
@@ -858,7 +886,7 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
858
886
  const {
859
887
  issueType
860
888
  } = this.issueReporterModel.getData();
861
- reset(typeSelect, makeOption(IssueType.Bug, ( localize(15640, "Bug Report"))), makeOption(IssueType.FeatureRequest, ( localize(15641, "Feature Request"))), makeOption(IssueType.PerformanceIssue, ( localize(15642, "Performance Issue (freeze, slow, crash)"))));
889
+ reset(typeSelect, makeOption(IssueType.Bug, ( localize(18054, "Bug Report"))), makeOption(IssueType.FeatureRequest, ( localize(18055, "Feature Request"))), makeOption(IssueType.PerformanceIssue, ( localize(18056, "Performance Issue (freeze, slow, crash)"))));
862
890
  typeSelect.value = ( issueType.toString());
863
891
  this.setSourceOptions();
864
892
  }
@@ -891,14 +919,14 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
891
919
  }
892
920
  }
893
921
  sourceSelect.innerText = "";
894
- sourceSelect.append(this.makeOption("", ( localize(15643, "Select source")), true));
895
- sourceSelect.append(this.makeOption(IssueSource.VSCode, ( localize(15644, "Visual Studio Code")), false));
896
- sourceSelect.append(this.makeOption(IssueSource.Extension, ( localize(15645, "A VS Code extension")), false));
922
+ sourceSelect.append(this.makeOption("", ( localize(18057, "Select source")), true));
923
+ sourceSelect.append(this.makeOption(IssueSource.VSCode, ( localize(18058, "Visual Studio Code")), false));
924
+ sourceSelect.append(this.makeOption(IssueSource.Extension, ( localize(18059, "A VS Code extension")), false));
897
925
  if (this.product.reportMarketplaceIssueUrl) {
898
- sourceSelect.append(this.makeOption(IssueSource.Marketplace, ( localize(15646, "Extensions Marketplace")), false));
926
+ sourceSelect.append(this.makeOption(IssueSource.Marketplace, ( localize(18060, "Extensions Marketplace")), false));
899
927
  }
900
928
  if (issueType !== IssueType.FeatureRequest) {
901
- sourceSelect.append(this.makeOption(IssueSource.Unknown, ( localize(15647, "Don't know")), false));
929
+ sourceSelect.append(this.makeOption(IssueSource.Unknown, ( localize(18061, "Don't know")), false));
902
930
  }
903
931
  if (selected !== -1 && selected < sourceSelect.options.length) {
904
932
  sourceSelect.selectedIndex = selected;
@@ -954,7 +982,7 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
954
982
  const fileName = `extensionData_${formattedDate}_${formattedTime}.md`;
955
983
  const handleLinkClick = async () => {
956
984
  const downloadPath = await this.fileDialogService.showSaveDialog({
957
- title: ( localize(15648, "Save Extension Data")),
985
+ title: ( localize(18062, "Save Extension Data")),
958
986
  availableFileSystems: [Schemas.file],
959
987
  defaultUri: joinPath(await this.fileDialogService.defaultFilePath(Schemas.file), fileName)
960
988
  });
@@ -970,13 +998,13 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
970
998
  if (selectedExtension && this.nonGitHubIssueUrl) {
971
999
  hide(titleTextArea);
972
1000
  hide(descriptionTextArea);
973
- reset(descriptionTitle, ( localize(15649, "This extension handles issues outside of VS Code")));
1001
+ reset(descriptionTitle, ( localize(18063, "This extension handles issues outside of VS Code")));
974
1002
  reset(descriptionSubtitle, ( localize(
975
- 15650,
1003
+ 18064,
976
1004
  "The '{0}' extension prefers to use an external issue reporter. To be taken to that issue reporting experience, click the button below.",
977
1005
  selectedExtension.displayName
978
1006
  )));
979
- this.publicGithubButton.label = ( localize(15651, "Open External Issue Reporter"));
1007
+ this.publicGithubButton.label = ( localize(18065, "Open External Issue Reporter"));
980
1008
  return;
981
1009
  }
982
1010
  if (fileOnExtension && selectedExtension?.data) {
@@ -1003,9 +1031,9 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
1003
1031
  show(extensionsBlock);
1004
1032
  }
1005
1033
  }
1006
- reset(descriptionTitle, ( localize(15652, "Steps to Reproduce")) + " ", $("span.required-input", undefined, "*"));
1034
+ reset(descriptionTitle, ( localize(18066, "Steps to Reproduce")) + " ", $("span.required-input", undefined, "*"));
1007
1035
  reset(descriptionSubtitle, ( localize(
1008
- 15653,
1036
+ 18067,
1009
1037
  "Share the steps needed to reliably reproduce the problem. Please include actual and expected results. We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub."
1010
1038
  )));
1011
1039
  } else if (issueType === IssueType.PerformanceIssue) {
@@ -1021,15 +1049,15 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
1021
1049
  } else if (!fileOnMarketplace) {
1022
1050
  show(extensionsBlock);
1023
1051
  }
1024
- reset(descriptionTitle, ( localize(15652, "Steps to Reproduce")) + " ", $("span.required-input", undefined, "*"));
1052
+ reset(descriptionTitle, ( localize(18066, "Steps to Reproduce")) + " ", $("span.required-input", undefined, "*"));
1025
1053
  reset(descriptionSubtitle, ( localize(
1026
- 15654,
1054
+ 18068,
1027
1055
  "When did this performance issue happen? Does it occur on startup or after a specific series of actions? We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub."
1028
1056
  )));
1029
1057
  } else if (issueType === IssueType.FeatureRequest) {
1030
- reset(descriptionTitle, ( localize(15655, "Description")) + " ", $("span.required-input", undefined, "*"));
1058
+ reset(descriptionTitle, ( localize(18069, "Description")) + " ", $("span.required-input", undefined, "*"));
1031
1059
  reset(descriptionSubtitle, ( localize(
1032
- 15656,
1060
+ 18070,
1033
1061
  "Please describe the feature you would like to see. We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub."
1034
1062
  )));
1035
1063
  }
@@ -1160,7 +1188,7 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
1160
1188
  throw ( new CancellationError());
1161
1189
  }
1162
1190
  return baseUrl + `&body=${encodeURIComponent(( localize(
1163
- 15657,
1191
+ 18071,
1164
1192
  "We have written the needed data into your clipboard because it was too large to send. Please paste."
1165
1193
  )))}`;
1166
1194
  }
@@ -1349,7 +1377,7 @@ let BaseIssueReporterService = class BaseIssueReporterService extends Disposable
1349
1377
  const target = this.window.document.querySelector(".block-extensions .block-info");
1350
1378
  if (target) {
1351
1379
  if (this.disableExtensions) {
1352
- reset(target, ( localize(15658, "Extensions are disabled")));
1380
+ reset(target, ( localize(18072, "Extensions are disabled")));
1353
1381
  return;
1354
1382
  }
1355
1383
  const themeExclusionStr = numThemeExtensions ? `\n(${numThemeExtensions} theme extensions excluded)` : "";
@@ -1416,7 +1444,7 @@ BaseIssueReporterService.__decorator = ( __decorate(
1416
1444
  "searchDuplicates",
1417
1445
  null
1418
1446
  ));
1419
- BaseIssueReporterService = ( __decorate([( __param(6, IIssueFormService)), ( __param(7, IThemeService)), ( __param(8, IFileService)), ( __param(9, IFileDialogService)), ( __param(10, IContextMenuService)), ( __param(11, IAuthenticationService)), ( __param(12, IOpenerService))], BaseIssueReporterService));
1447
+ BaseIssueReporterService = ( __decorate([( __param(7, IIssueFormService)), ( __param(8, IThemeService)), ( __param(9, IFileService)), ( __param(10, IFileDialogService)), ( __param(11, IContextMenuService)), ( __param(12, IAuthenticationService)), ( __param(13, IOpenerService)), ( __param(14, ILogService))], BaseIssueReporterService));
1420
1448
  function hide(el) {
1421
1449
  el?.classList.add("hidden");
1422
1450
  }
@@ -33,5 +33,5 @@ let WebIssueContribution = class WebIssueContribution extends BaseIssueContribut
33
33
  WebIssueContribution = ( __decorate([( __param(0, IProductService)), ( __param(1, IConfigurationService))], WebIssueContribution));
34
34
  ( Registry.as(Extensions$1.Workbench)).registerWorkbenchContribution(WebIssueContribution, LifecyclePhase.Restored);
35
35
  CommandsRegistry.registerCommand("_issues.getSystemStatus", accessor => {
36
- return localize(15659, "The --status argument is not yet supported in browsers.");
36
+ return localize(18073, "The --status argument is not yet supported in browsers.");
37
37
  });
@@ -1,16 +1,17 @@
1
- import { Disposable } from "@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle";
1
+ import { Disposable, DisposableStore } from "@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle";
2
2
  import { IMenuService } from "@codingame/monaco-vscode-api/vscode/vs/platform/actions/common/actions.service";
3
3
  import { IClipboardService } from "@codingame/monaco-vscode-api/vscode/vs/platform/clipboard/common/clipboardService.service";
4
4
  import { IContextKeyService } from "@codingame/monaco-vscode-api/vscode/vs/platform/contextkey/common/contextkey.service";
5
5
  import { IDialogService } from "@codingame/monaco-vscode-api/vscode/vs/platform/dialogs/common/dialogs.service";
6
6
  import { ExtensionIdentifierSet } from "@codingame/monaco-vscode-api/vscode/vs/platform/extensions/common/extensions";
7
7
  import { IInstantiationService } from "@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/instantiation";
8
+ import { IGitHubService } from "@codingame/monaco-vscode-api/vscode/vs/platform/github/common/githubService.service";
8
9
  import { ILogService } from "@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service";
9
10
  import { IOpenerService } from "@codingame/monaco-vscode-api/vscode/vs/platform/opener/common/opener.service";
10
11
  import { IRectangle } from "@codingame/monaco-vscode-api/vscode/vs/platform/window/common/window";
11
12
  import { IAuxiliaryWindowService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService.service";
12
13
  import { IHostService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/host/browser/host.service";
13
- import { IIssueSubmissionHost, IssueReporterData } from "../common/issue.js";
14
+ import { IIssueSubmissionHost, ISimilarIssue, IssueReporterData } from "../common/issue.js";
14
15
  import { IIssueFormService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/issue/common/issue.service";
15
16
  import { IGitHubUploadService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/issue/browser/githubUploadService.service";
16
17
  import { IFileService } from "@codingame/monaco-vscode-api/vscode/vs/platform/files/common/files.service";
@@ -33,6 +34,7 @@ export declare class IssueFormService extends Disposable implements IIssueFormSe
33
34
  protected readonly githubUploadService: IGitHubUploadService;
34
35
  protected readonly editorService: IEditorService;
35
36
  protected readonly clipboardService: IClipboardService;
37
+ private readonly gitHubService;
36
38
  readonly _serviceBrand: undefined;
37
39
  protected currentData: IssueReporterData | undefined;
38
40
  protected issueReporterWindow: Window | null;
@@ -42,7 +44,9 @@ export declare class IssueFormService extends Disposable implements IIssueFormSe
42
44
  protected type: string;
43
45
  /** Bounded cache of already-uploaded attachments to avoid re-uploading on retry within a session. Uses a content hash so large data URLs aren't retained as keys. */
44
46
  private readonly uploadCache;
45
- constructor(instantiationService: IInstantiationService, auxiliaryWindowService: IAuxiliaryWindowService, menuService: IMenuService, contextKeyService: IContextKeyService, logService: ILogService, dialogService: IDialogService, hostService: IHostService, openerService: IOpenerService, fileService: IFileService, githubUploadService: IGitHubUploadService, editorService: IEditorService, clipboardService: IClipboardService);
47
+ private readonly gitHubSearchClient;
48
+ constructor(instantiationService: IInstantiationService, auxiliaryWindowService: IAuxiliaryWindowService, menuService: IMenuService, contextKeyService: IContextKeyService, logService: ILogService, dialogService: IDialogService, hostService: IHostService, openerService: IOpenerService, fileService: IFileService, githubUploadService: IGitHubUploadService, editorService: IEditorService, clipboardService: IClipboardService, gitHubService: IGitHubService);
49
+ searchGitHubIssues(repo: string, title: string, signal: AbortSignal): Promise<readonly ISimilarIssue[]>;
46
50
  openReporter(data: IssueReporterData): Promise<void>;
47
51
  submitIssue(host: IIssueSubmissionHost, data: IssueReporterData, title: string, body: string): Promise<boolean>;
48
52
  private tryCreateBodyWithIssueDataAttachment;
@@ -59,7 +63,7 @@ export declare class IssueFormService extends Disposable implements IIssueFormSe
59
63
  private dataUrlToBytes;
60
64
  /** Opens the classic non-wizard reporter in an auxiliary window. */
61
65
  openAuxIssueReporterLegacy(data: IssueReporterData): Promise<void>;
62
- openAuxIssueReporter(data: IssueReporterData, bounds?: IRectangle): Promise<void>;
66
+ openAuxIssueReporter(data: IssueReporterData, bounds?: IRectangle): Promise<DisposableStore>;
63
67
  sendReporterMenu(extensionId: string): Promise<IssueReporterData | undefined>;
64
68
  closeReporter(): Promise<void>;
65
69
  reloadWithExtensionsDisabled(): Promise<void>;
@@ -5,7 +5,7 @@ import { createElement } from '@codingame/monaco-vscode-api/vscode/vs/base/brows
5
5
  import { safeSetInnerHtml } from '@codingame/monaco-vscode-api/vscode/vs/base/browser/domSanitize';
6
6
  import { createStyleSheet } from '@codingame/monaco-vscode-api/vscode/vs/base/browser/domStylesheets';
7
7
  import { Menu, getMenuWidgetCSS, unthemedMenuStyles } from '@codingame/monaco-vscode-api/vscode/vs/base/browser/ui/menu/menu';
8
- import { Disposable, DisposableStore } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
8
+ import { Disposable, MutableDisposable, DisposableStore } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
9
9
  import { isWindows, isLinux } from '@codingame/monaco-vscode-api/vscode/vs/base/common/platform';
10
10
  import Severity from '@codingame/monaco-vscode-api/vscode/vs/base/common/severity';
11
11
  import { localize } from '@codingame/monaco-vscode-api/vscode/vs/nls';
@@ -16,6 +16,9 @@ import { IContextKeyService } from '@codingame/monaco-vscode-api/vscode/vs/platf
16
16
  import { IDialogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/dialogs/common/dialogs.service';
17
17
  import { ExtensionIdentifierSet, ExtensionIdentifier } from '@codingame/monaco-vscode-api/vscode/vs/platform/extensions/common/extensions';
18
18
  import { IInstantiationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/instantiation';
19
+ import { IGitHubService } from '@codingame/monaco-vscode-api/vscode/vs/platform/github/common/githubService.service';
20
+ import { GitHubRequestError } from '@codingame/monaco-vscode-api/vscode/vs/platform/github/common/githubTypes';
21
+ import { arrayProperty, asObject, stringProperty, requiredString } from '@codingame/monaco-vscode-api/vscode/vs/platform/github/common/githubResponse';
19
22
  import { ILogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service';
20
23
  import { IOpenerService } from '@codingame/monaco-vscode-api/vscode/vs/platform/opener/common/opener.service';
21
24
  import product from '@codingame/monaco-vscode-api/vscode/vs/platform/product/common/product';
@@ -71,7 +74,7 @@ function extractIssueData(issueBody) {
71
74
  bodyParts.push(issueBody.slice(bodyStart));
72
75
  return {
73
76
  body: bodyParts.join("\n\n").replace(/\n{3,}/g, "\n\n").trimEnd(),
74
- fileContent: `# ${( localize(15660, "Issue Data"))}\n\n${detailsBlocks.join("\n\n")}\n`
77
+ fileContent: `# ${( localize(18074, "Issue Data"))}\n\n${detailsBlocks.join("\n\n")}\n`
75
78
  };
76
79
  }
77
80
  let IssueFormService = class IssueFormService extends Disposable {
@@ -87,7 +90,8 @@ let IssueFormService = class IssueFormService extends Disposable {
87
90
  fileService,
88
91
  githubUploadService,
89
92
  editorService,
90
- clipboardService
93
+ clipboardService,
94
+ gitHubService
91
95
  ) {
92
96
  super();
93
97
  this.instantiationService = instantiationService;
@@ -102,12 +106,47 @@ let IssueFormService = class IssueFormService extends Disposable {
102
106
  this.githubUploadService = githubUploadService;
103
107
  this.editorService = editorService;
104
108
  this.clipboardService = clipboardService;
109
+ this.gitHubService = gitHubService;
105
110
  this.issueReporterWindow = null;
106
111
  this.extensionIdentifierSet = ( new ExtensionIdentifierSet());
107
112
  this.arch = "";
108
113
  this.release = "";
109
114
  this.type = "";
110
115
  this.uploadCache = ( new LRUCache(32));
116
+ this.gitHubSearchClient = this._register(( new MutableDisposable()));
117
+ }
118
+ async searchGitHubIssues(repo, title, signal) {
119
+ signal.throwIfAborted();
120
+ if (this._store.isDisposed) {
121
+ throw ( new GitHubRequestError("Issue reporter was disposed", "unknown"));
122
+ }
123
+ this.gitHubSearchClient.value ??= this.gitHubService.acquireAnonymousClient({
124
+ apiBaseUri: "https://api.github.com"
125
+ });
126
+ const query = encodeURIComponent(`is:issue repo:${repo} ${title}`);
127
+ try {
128
+ const response = await this.gitHubSearchClient.value.object.get(`/search/issues?q=${query}`, signal, {
129
+ caller: "github.query",
130
+ deadline: Date.now() + 10_000
131
+ });
132
+ const items = arrayProperty(
133
+ asObject(response.data, "GitHub issue search response was malformed"),
134
+ "items"
135
+ );
136
+ return items.map(item => {
137
+ const issue = asObject(item, "GitHub issue search result was malformed");
138
+ return {
139
+ html_url: requiredString(issue, "html_url"),
140
+ title: requiredString(issue, "title"),
141
+ state: stringProperty(issue, "state")
142
+ };
143
+ });
144
+ } catch (error) {
145
+ if (!signal.aborted) {
146
+ this.logService.warn("[IssueFormService] GitHub issue search failed", error);
147
+ }
148
+ throw error;
149
+ }
111
150
  }
112
151
  async openReporter(data) {
113
152
  if (this.hasToReload(data)) {
@@ -195,14 +234,14 @@ let IssueFormService = class IssueFormService extends Disposable {
195
234
  uploadResults.push(result);
196
235
  host.setAttachmentUploadState(i, "done");
197
236
  }
198
- mediaMarkdown = `\n\n### ${( localize(15661, "Attachments"))}\n\n`;
237
+ mediaMarkdown = `\n\n### ${( localize(18075, "Attachments"))}\n\n`;
199
238
  for (const r of uploadResults) {
200
239
  mediaMarkdown += r.contentType.startsWith("video/") ? `${r.assetUrl}\n\n` : `![${r.fileName}](${r.assetUrl})\n\n`;
201
240
  }
202
241
  }
203
242
  } catch (err) {
204
243
  this.logService.error("[IssueFormService] Upload failed:", err);
205
- mediaMarkdown = `\n\n### ${( localize(15661, "Attachments"))}\n\n> ${( localize(15662, "Upload failed. Please drag and drop attachments manually."))}\n\n`;
244
+ mediaMarkdown = `\n\n### ${( localize(18075, "Attachments"))}\n\n> ${( localize(18076, "Upload failed. Please drag and drop attachments manually."))}\n\n`;
206
245
  } finally {
207
246
  host.setUploading(false);
208
247
  }
@@ -238,7 +277,7 @@ let IssueFormService = class IssueFormService extends Disposable {
238
277
  return false;
239
278
  }
240
279
  url = this.createIssuePreviewUrl(baseUrl, ( localize(
241
- 15663,
280
+ 18077,
242
281
  "We have written the needed data into your clipboard because it was too large to send. Please paste."
243
282
  )), gitHubDetails, data.issueSource);
244
283
  }
@@ -301,7 +340,7 @@ let IssueFormService = class IssueFormService extends Disposable {
301
340
  return result;
302
341
  }
303
342
  createBodyWithIssueDataLink(body, issueDataUrl) {
304
- const attachmentMarkdown = `\n\n### ${( localize(15664, "Additional Issue Data"))}\n\n[${ISSUE_DATA_ATTACHMENT_NAME}](${issueDataUrl})`;
343
+ const attachmentMarkdown = `\n\n### ${( localize(18078, "Additional Issue Data"))}\n\n[${ISSUE_DATA_ATTACHMENT_NAME}](${issueDataUrl})`;
305
344
  const markerIndex = body.indexOf(GENERATED_BY_ISSUE_REPORTER_MARKER);
306
345
  if (markerIndex === -1) {
307
346
  return `${body.trimEnd()}${attachmentMarkdown}\n`;
@@ -410,13 +449,13 @@ let IssueFormService = class IssueFormService extends Disposable {
410
449
  }
411
450
  }
412
451
  async openAuxIssueReporterLegacy(data) {
413
- await this.openAuxIssueReporter(data);
452
+ const disposables = await this.openAuxIssueReporter(data);
414
453
  if (this.issueReporterWindow) {
415
- const issueReporter = this.instantiationService.createInstance(IssueWebReporter, false, data, {
454
+ const issueReporter = disposables.add(this.instantiationService.createInstance(IssueWebReporter, false, data, {
416
455
  type: this.type,
417
456
  arch: this.arch,
418
457
  release: this.release
419
- }, product, this.issueReporterWindow);
458
+ }, product, this.issueReporterWindow));
420
459
  issueReporter.render();
421
460
  }
422
461
  }
@@ -472,6 +511,7 @@ let IssueFormService = class IssueFormService extends Disposable {
472
511
  disposables.dispose();
473
512
  this.issueReporterWindow = null;
474
513
  });
514
+ return disposables;
475
515
  }
476
516
  async sendReporterMenu(extensionId) {
477
517
  const menu = this.menuService.createMenu(MenuId.IssueReporter, this.contextKeyService);
@@ -515,17 +555,17 @@ let IssueFormService = class IssueFormService extends Disposable {
515
555
  await this.dialogService.prompt({
516
556
  type: Severity.Warning,
517
557
  message: ( localize(
518
- 15665,
558
+ 18079,
519
559
  "Your input will not be saved. Are you sure you want to close this window?"
520
560
  )),
521
561
  buttons: [{
522
- label: ( localize(15666, "&&Yes")),
562
+ label: ( localize(18080, "&&Yes")),
523
563
  run: () => {
524
564
  this.closeReporter();
525
565
  this.issueReporterWindow = null;
526
566
  }
527
567
  }, {
528
- label: ( localize(15667, "Cancel")),
568
+ label: ( localize(18081, "Cancel")),
529
569
  run: () => {}
530
570
  }]
531
571
  });
@@ -535,16 +575,16 @@ let IssueFormService = class IssueFormService extends Disposable {
535
575
  await this.dialogService.prompt({
536
576
  type: Severity.Warning,
537
577
  message: ( localize(
538
- 15668,
578
+ 18082,
539
579
  "There is too much data to send to GitHub directly. The data will be copied to the clipboard, please paste it into the GitHub issue page that is opened."
540
580
  )),
541
581
  buttons: [{
542
- label: ( localize(15669, "&&OK")),
582
+ label: ( localize(18083, "&&OK")),
543
583
  run: () => {
544
584
  result = true;
545
585
  }
546
586
  }, {
547
- label: ( localize(15667, "Cancel")),
587
+ label: ( localize(18081, "Cancel")),
548
588
  run: () => {
549
589
  result = false;
550
590
  }
@@ -565,6 +605,6 @@ let IssueFormService = class IssueFormService extends Disposable {
565
605
  return false;
566
606
  }
567
607
  };
568
- IssueFormService = ( __decorate([( __param(0, IInstantiationService)), ( __param(1, IAuxiliaryWindowService)), ( __param(2, IMenuService)), ( __param(3, IContextKeyService)), ( __param(4, ILogService)), ( __param(5, IDialogService)), ( __param(6, IHostService)), ( __param(7, IOpenerService)), ( __param(8, IFileService)), ( __param(9, IGitHubUploadService)), ( __param(10, IEditorService)), ( __param(11, IClipboardService))], IssueFormService));
608
+ IssueFormService = ( __decorate([( __param(0, IInstantiationService)), ( __param(1, IAuxiliaryWindowService)), ( __param(2, IMenuService)), ( __param(3, IContextKeyService)), ( __param(4, ILogService)), ( __param(5, IDialogService)), ( __param(6, IHostService)), ( __param(7, IOpenerService)), ( __param(8, IFileService)), ( __param(9, IGitHubUploadService)), ( __param(10, IEditorService)), ( __param(11, IClipboardService)), ( __param(12, IGitHubService))], IssueFormService));
569
609
 
570
610
  export { IssueFormService, extractIssueData };
@@ -1,3 +1,4 @@
1
+ import { Disposable } from "@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle";
1
2
  import { SystemInfo } from "@codingame/monaco-vscode-api/vscode/vs/platform/diagnostics/common/diagnostics";
2
3
  import { ISettingSearchResult, IssueReporterExtensionData, IssueSource, IssueType } from "../common/issue.js";
3
4
  interface VersionInfo {
@@ -37,7 +38,7 @@ export interface IssueReporterData {
37
38
  isInstallationPure?: boolean;
38
39
  isSessionsWindow?: boolean;
39
40
  }
40
- export declare class IssueReporterModel {
41
+ export declare class IssueReporterModel extends Disposable {
41
42
  private readonly _data;
42
43
  constructor(initialData?: Partial<IssueReporterData>);
43
44
  getData(): IssueReporterData;
@@ -1,10 +1,13 @@
1
1
 
2
+ import { addDisposableListener } from '@codingame/monaco-vscode-api/vscode/vs/base/browser/dom';
3
+ import { Disposable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
2
4
  import { mainWindow } from '@codingame/monaco-vscode-api/vscode/vs/base/browser/window';
3
5
  import { isRemoteDiagnosticError } from '@codingame/monaco-vscode-api/vscode/vs/platform/diagnostics/common/diagnostics';
4
6
  import { IssueType } from '../common/issue.js';
5
7
 
6
- class IssueReporterModel {
8
+ class IssueReporterModel extends Disposable {
7
9
  constructor(initialData) {
10
+ super();
8
11
  const defaultData = {
9
12
  issueType: IssueType.Bug,
10
13
  includeSystemInfo: true,
@@ -16,7 +19,7 @@ class IssueReporterModel {
16
19
  allExtensions: []
17
20
  };
18
21
  this._data = initialData ? Object.assign(defaultData, initialData) : defaultData;
19
- mainWindow.addEventListener("message", async event => {
22
+ this._register(addDisposableListener(mainWindow, "message", event => {
20
23
  if (event.data && event.data.sendChannel === "vscode:triggerIssueData") {
21
24
  mainWindow.postMessage({
22
25
  data: {
@@ -26,7 +29,7 @@ class IssueReporterModel {
26
29
  replyChannel: "vscode:triggerIssueDataResponse"
27
30
  }, "*");
28
31
  }
29
- });
32
+ }));
30
33
  }
31
34
  getData() {
32
35
  return this._data;
@@ -2,18 +2,18 @@
2
2
  import { escape } from '@codingame/monaco-vscode-api/vscode/vs/base/common/strings';
3
3
  import { localize } from '@codingame/monaco-vscode-api/vscode/vs/nls';
4
4
 
5
- const sendSystemInfoLabel = escape(( localize(15670, "Include my system information")));
6
- const sendProcessInfoLabel = escape(( localize(15671, "Include my currently running processes")));
7
- const sendWorkspaceInfoLabel = escape(( localize(15672, "Include my workspace metadata")));
8
- const sendExtensionsLabel = escape(( localize(15673, "Include my enabled extensions")));
9
- const sendExperimentsLabel = escape(( localize(15674, "Include A/B experiment info")));
10
- const sendExtensionData = escape(( localize(15675, "Include additional extension info")));
5
+ const sendSystemInfoLabel = escape(( localize(18084, "Include my system information")));
6
+ const sendProcessInfoLabel = escape(( localize(18085, "Include my currently running processes")));
7
+ const sendWorkspaceInfoLabel = escape(( localize(18086, "Include my workspace metadata")));
8
+ const sendExtensionsLabel = escape(( localize(18087, "Include my enabled extensions")));
9
+ const sendExperimentsLabel = escape(( localize(18088, "Include A/B experiment info")));
10
+ const sendExtensionData = escape(( localize(18089, "Include additional extension info")));
11
11
  const acknowledgementsLabel = escape(( localize(
12
- 15676,
12
+ 18090,
13
13
  "I acknowledge that my VS Code version is not updated and this issue may be closed."
14
14
  )));
15
15
  const reviewGuidanceLabel = ( localize(
16
- 15677,
16
+ 18091,
17
17
  "Before you report an issue here please <a href=\"https://github.com/microsoft/vscode/wiki/Submitting-Bugs-and-Suggestions\" target=\"_blank\">review the guidance we provide</a>. Please complete the form in English."
18
18
  ));
19
19
  var BaseHtml = () => `
@@ -23,40 +23,40 @@ var BaseHtml = () => `
23
23
  </span>
24
24
  </div>
25
25
  <div class="issue-reporter" id="issue-reporter">
26
- <div id="english" class="input-group hidden">${escape(( localize(15678, "Please complete the form in English.")))}</div>
26
+ <div id="english" class="input-group hidden">${escape(( localize(18092, "Please complete the form in English.")))}</div>
27
27
 
28
28
  <div id="review-guidance-help-text" class="input-group">${reviewGuidanceLabel}</div>
29
29
 
30
30
  <div class="section">
31
31
  <div class="input-group">
32
- <label class="inline-label" for="issue-type">${escape(( localize(15679, "This is a")))}</label>
32
+ <label class="inline-label" for="issue-type">${escape(( localize(18093, "This is a")))}</label>
33
33
  <select id="issue-type" class="inline-form-control">
34
34
  <!-- To be dynamically filled -->
35
35
  </select>
36
36
  </div>
37
37
 
38
38
  <div class="input-group" id="problem-source">
39
- <label class="inline-label" for="issue-source">${escape(( localize(15680, "For")))} <span class="required-input">*</span></label>
39
+ <label class="inline-label" for="issue-source">${escape(( localize(18094, "For")))} <span class="required-input">*</span></label>
40
40
  <select id="issue-source" class="inline-form-control" required>
41
41
  <!-- To be dynamically filled -->
42
42
  </select>
43
- <div id="issue-source-empty-error" class="validation-error hidden" role="alert">${escape(( localize(15681, "An issue source is required.")))}</div>
43
+ <div id="issue-source-empty-error" class="validation-error hidden" role="alert">${escape(( localize(18095, "An issue source is required.")))}</div>
44
44
  <div id="problem-source-help-text" class="instructions hidden">${escape(( localize(
45
- 15682,
45
+ 18096,
46
46
  "Try to reproduce the problem after {0}. If the problem only reproduces when extensions are active, it is likely an issue with an extension."
47
47
  ))).replace(
48
48
  "{0}",
49
- () => `<span tabIndex=0 role="button" id="disableExtensions" class="workbenchCommand">${escape(( localize(15683, "disabling all extensions and reloading the window")))}</span>`
49
+ () => `<span tabIndex=0 role="button" id="disableExtensions" class="workbenchCommand">${escape(( localize(18097, "disabling all extensions and reloading the window")))}</span>`
50
50
  )}
51
51
  </div>
52
52
 
53
53
  <div id="extension-selection">
54
- <label class="inline-label" for="extension-selector">${escape(( localize(15684, "Extension")))} <span class="required-input">*</span></label>
54
+ <label class="inline-label" for="extension-selector">${escape(( localize(18098, "Extension")))} <span class="required-input">*</span></label>
55
55
  <select id="extension-selector" class="inline-form-control">
56
56
  <!-- To be dynamically filled -->
57
57
  </select>
58
58
  <div id="extension-selection-validation-error" class="validation-error hidden" role="alert">${escape(( localize(
59
- 15685,
59
+ 18099,
60
60
  "The issue reporter is unable to create issues for this extension. Please visit {0} to report an issue."
61
61
  ))).replace(
62
62
  "{0}",
@@ -64,7 +64,7 @@ var BaseHtml = () => `
64
64
  )}</div>
65
65
  <div id="extension-selection-validation-error-no-url" class="validation-error hidden" role="alert">
66
66
  ${escape(( localize(
67
- 15686,
67
+ 18100,
68
68
  "The issue reporter is unable to create issues for this extension, as it does not specify a URL for reporting issues. Please check the marketplace page of this extension to see if other instructions are available."
69
69
  )))}
70
70
  </div>
@@ -72,10 +72,10 @@ var BaseHtml = () => `
72
72
  </div>
73
73
 
74
74
  <div id="issue-title-container" class="input-group">
75
- <label class="inline-label" for="issue-title">${escape(( localize(15687, "Title")))} <span class="required-input">*</span></label>
76
- <input id="issue-title" type="text" class="inline-form-control" placeholder="${escape(( localize(15688, "Please enter a title.")))}" required>
77
- <div id="issue-title-empty-error" class="validation-error hidden" role="alert">${escape(( localize(15689, "A title is required.")))}</div>
78
- <div id="issue-title-length-validation-error" class="validation-error hidden" role="alert">${escape(( localize(15690, "The title is too long.")))}</div>
75
+ <label class="inline-label" for="issue-title">${escape(( localize(18101, "Title")))} <span class="required-input">*</span></label>
76
+ <input id="issue-title" type="text" class="inline-form-control" placeholder="${escape(( localize(18102, "Please enter a title.")))}" required>
77
+ <div id="issue-title-empty-error" class="validation-error hidden" role="alert">${escape(( localize(18103, "A title is required.")))}</div>
78
+ <div id="issue-title-length-validation-error" class="validation-error hidden" role="alert">${escape(( localize(18104, "The title is too long.")))}</div>
79
79
  <small id="similar-issues">
80
80
  <!-- To be dynamically filled -->
81
81
  </small>
@@ -91,10 +91,10 @@ var BaseHtml = () => `
91
91
  <!-- To be dynamically filled -->
92
92
  </div>
93
93
  <div class="block-info-text">
94
- <textarea name="description" id="description" placeholder="${escape(( localize(15691, "Please enter details.")))}" required></textarea>
94
+ <textarea name="description" id="description" placeholder="${escape(( localize(18105, "Please enter details.")))}" required></textarea>
95
95
  </div>
96
- <div id="description-empty-error" class="validation-error hidden" role="alert">${escape(( localize(15692, "A description is required.")))}</div>
97
- <div id="description-short-error" class="validation-error hidden" role="alert">${escape(( localize(15693, "Please provide a longer description.")))}</div>
96
+ <div id="description-empty-error" class="validation-error hidden" role="alert">${escape(( localize(18106, "A description is required.")))}</div>
97
+ <div id="description-short-error" class="validation-error hidden" role="alert">${escape(( localize(18107, "Please provide a longer description.")))}</div>
98
98
  </div>
99
99
 
100
100
  <div class="system-info" id="block-container">
@@ -103,10 +103,10 @@ var BaseHtml = () => `
103
103
  <label class="extension-caption" id="extension-caption" for="includeExtensionData">
104
104
  ${sendExtensionData}
105
105
  <span id="ext-loading" hidden></span>
106
- <span class="ext-parens" hidden>(</span><a href="#" class="showInfo" id="extension-id">${escape(( localize(15694, "show")))}</a><span class="ext-parens" hidden>)</span>
107
- <a id="extension-data-download">${escape(( localize(15695, "Download Extension Data")))}</a>
106
+ <span class="ext-parens" hidden>(</span><a href="#" class="showInfo" id="extension-id">${escape(( localize(18108, "show")))}</a><span class="ext-parens" hidden>)</span>
107
+ <a id="extension-data-download">${escape(( localize(18109, "Download Extension Data")))}</a>
108
108
  </label>
109
- <pre class="block-info" id="extension-data" placeholder="${escape(( localize(15696, "Extension does not have additional data to include.")))}" style="white-space: pre-wrap; user-select: text;">
109
+ <pre class="block-info" id="extension-data" placeholder="${escape(( localize(18110, "Extension does not have additional data to include.")))}" style="white-space: pre-wrap; user-select: text;">
110
110
  <!-- To be dynamically filled -->
111
111
  </pre>
112
112
  </div>
@@ -115,7 +115,7 @@ var BaseHtml = () => `
115
115
  <input class="sendData" aria-label="${sendSystemInfoLabel}" type="checkbox" id="includeSystemInfo" checked/>
116
116
  <label class="caption" for="includeSystemInfo">
117
117
  ${sendSystemInfoLabel}
118
- (<a href="#" class="showInfo">${escape(( localize(15694, "show")))}</a>)
118
+ (<a href="#" class="showInfo">${escape(( localize(18108, "show")))}</a>)
119
119
  </label>
120
120
  <div class="block-info hidden" style="user-select: text;">
121
121
  <!-- To be dynamically filled -->
@@ -125,7 +125,7 @@ var BaseHtml = () => `
125
125
  <input class="sendData" aria-label="${sendProcessInfoLabel}" type="checkbox" id="includeProcessInfo" checked/>
126
126
  <label class="caption" for="includeProcessInfo">
127
127
  ${sendProcessInfoLabel}
128
- (<a href="#" class="showInfo">${escape(( localize(15694, "show")))}</a>)
128
+ (<a href="#" class="showInfo">${escape(( localize(18108, "show")))}</a>)
129
129
  </label>
130
130
  <pre class="block-info hidden" style="user-select: text;">
131
131
  <code>
@@ -137,7 +137,7 @@ var BaseHtml = () => `
137
137
  <input class="sendData" aria-label="${sendWorkspaceInfoLabel}" type="checkbox" id="includeWorkspaceInfo" checked/>
138
138
  <label class="caption" for="includeWorkspaceInfo">
139
139
  ${sendWorkspaceInfoLabel}
140
- (<a href="#" class="showInfo">${escape(( localize(15694, "show")))}</a>)
140
+ (<a href="#" class="showInfo">${escape(( localize(18108, "show")))}</a>)
141
141
  </label>
142
142
  <pre id="systemInfo" class="block-info hidden" style="user-select: text;">
143
143
  <code>
@@ -149,7 +149,7 @@ var BaseHtml = () => `
149
149
  <input class="sendData" aria-label="${sendExtensionsLabel}" type="checkbox" id="includeExtensions" checked/>
150
150
  <label class="caption" for="includeExtensions">
151
151
  ${sendExtensionsLabel}
152
- (<a href="#" class="showInfo">${escape(( localize(15694, "show")))}</a>)
152
+ (<a href="#" class="showInfo">${escape(( localize(18108, "show")))}</a>)
153
153
  </label>
154
154
  <div id="systemInfo" class="block-info hidden" style="user-select: text;">
155
155
  <!-- To be dynamically filled -->
@@ -159,7 +159,7 @@ var BaseHtml = () => `
159
159
  <input class="sendData" aria-label="${sendExperimentsLabel}" type="checkbox" id="includeExperiments" checked/>
160
160
  <label class="caption" for="includeExperiments">
161
161
  ${sendExperimentsLabel}
162
- (<a href="#" class="showInfo">${escape(( localize(15694, "show")))}</a>)
162
+ (<a href="#" class="showInfo">${escape(( localize(18108, "show")))}</a>)
163
163
  </label>
164
164
  <pre class="block-info hidden" style="user-select: text;">
165
165
  <!-- To be dynamically filled -->
@@ -2,6 +2,7 @@ import { IProductConfiguration } from "@codingame/monaco-vscode-api/vscode/vs/ba
2
2
  import { IContextMenuService } from "@codingame/monaco-vscode-api/vscode/vs/platform/contextview/browser/contextView.service";
3
3
  import { IFileDialogService } from "@codingame/monaco-vscode-api/vscode/vs/platform/dialogs/common/dialogs.service";
4
4
  import { IFileService } from "@codingame/monaco-vscode-api/vscode/vs/platform/files/common/files.service";
5
+ import { ILogService } from "@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service";
5
6
  import { IOpenerService } from "@codingame/monaco-vscode-api/vscode/vs/platform/opener/common/opener.service";
6
7
  import { IThemeService } from "@codingame/monaco-vscode-api/vscode/vs/platform/theme/common/themeService.service";
7
8
  import { IAuthenticationService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/authentication/common/authentication.service";
@@ -13,6 +14,6 @@ export declare class IssueWebReporter extends BaseIssueReporterService {
13
14
  type: string;
14
15
  arch: string;
15
16
  release: string;
16
- }, product: IProductConfiguration, window: Window, issueFormService: IIssueFormService, themeService: IThemeService, fileService: IFileService, fileDialogService: IFileDialogService, contextMenuService: IContextMenuService, authenticationService: IAuthenticationService, openerService: IOpenerService);
17
+ }, product: IProductConfiguration, window: Window, issueFormService: IIssueFormService, themeService: IThemeService, fileService: IFileService, fileDialogService: IFileDialogService, contextMenuService: IContextMenuService, authenticationService: IAuthenticationService, openerService: IOpenerService, logService: ILogService);
17
18
  setEventHandlers(): void;
18
19
  }
@@ -4,6 +4,7 @@ import { localize } from '@codingame/monaco-vscode-api/vscode/vs/nls';
4
4
  import { IContextMenuService } from '@codingame/monaco-vscode-api/vscode/vs/platform/contextview/browser/contextView.service';
5
5
  import { IFileDialogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/dialogs/common/dialogs.service';
6
6
  import { IFileService } from '@codingame/monaco-vscode-api/vscode/vs/platform/files/common/files.service';
7
+ import { ILogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service';
7
8
  import { IOpenerService } from '@codingame/monaco-vscode-api/vscode/vs/platform/opener/common/opener.service';
8
9
  import { IThemeService } from '@codingame/monaco-vscode-api/vscode/vs/platform/theme/common/themeService.service';
9
10
  import { IAuthenticationService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/authentication/common/authentication.service';
@@ -23,7 +24,8 @@ let IssueWebReporter = class IssueWebReporter extends BaseIssueReporterService {
23
24
  fileDialogService,
24
25
  contextMenuService,
25
26
  authenticationService,
26
- openerService
27
+ openerService,
28
+ logService
27
29
  ) {
28
30
  super(
29
31
  disableExtensions,
@@ -32,13 +34,15 @@ let IssueWebReporter = class IssueWebReporter extends BaseIssueReporterService {
32
34
  product,
33
35
  window,
34
36
  true,
37
+ undefined,
35
38
  issueFormService,
36
39
  themeService,
37
40
  fileService,
38
41
  fileDialogService,
39
42
  contextMenuService,
40
43
  authenticationService,
41
- openerService
44
+ openerService,
45
+ logService
42
46
  );
43
47
  const target = this.window.document.querySelector(".block-system .block-info");
44
48
  const webInfo = this.window.navigator.userAgent;
@@ -60,7 +64,7 @@ let IssueWebReporter = class IssueWebReporter extends BaseIssueReporterService {
60
64
  });
61
65
  const descriptionTextArea = this.getElementById("issue-title");
62
66
  if (descriptionTextArea) {
63
- descriptionTextArea.placeholder = ( localize(15697, "Please enter a title"));
67
+ descriptionTextArea.placeholder = ( localize(18111, "Please enter a title"));
64
68
  }
65
69
  this.updateButtonStates();
66
70
  this.setSourceOptions();
@@ -68,6 +72,6 @@ let IssueWebReporter = class IssueWebReporter extends BaseIssueReporterService {
68
72
  });
69
73
  }
70
74
  };
71
- IssueWebReporter = ( __decorate([( __param(5, IIssueFormService)), ( __param(6, IThemeService)), ( __param(7, IFileService)), ( __param(8, IFileDialogService)), ( __param(9, IContextMenuService)), ( __param(10, IAuthenticationService)), ( __param(11, IOpenerService))], IssueWebReporter));
75
+ IssueWebReporter = ( __decorate([( __param(5, IIssueFormService)), ( __param(6, IThemeService)), ( __param(7, IFileService)), ( __param(8, IFileDialogService)), ( __param(9, IContextMenuService)), ( __param(10, IAuthenticationService)), ( __param(11, IOpenerService)), ( __param(12, ILogService))], IssueWebReporter));
72
76
 
73
77
  export { IssueWebReporter };
@@ -102,13 +102,13 @@ let TroubleshootIssueService = class TroubleshootIssueService extends Disposable
102
102
  throw ( new Error("invalid state"));
103
103
  }
104
104
  const res = await this.dialogService.confirm({
105
- message: ( localize(15698, "Troubleshoot Issue")),
105
+ message: ( localize(18112, "Troubleshoot Issue")),
106
106
  detail: ( localize(
107
- 15699,
107
+ 18113,
108
108
  "Issue troubleshooting is a process to help you identify the cause for an issue. The cause for an issue can be a misconfiguration, due to an extension, or be {0} itself.\n\nDuring the process the window reloads repeatedly. Each time you must confirm if you are still seeing the issue.",
109
109
  this.productService.nameLong
110
110
  )),
111
- primaryButton: ( localize(15700, "&&Troubleshoot Issue")),
111
+ primaryButton: ( localize(18114, "&&Troubleshoot Issue")),
112
112
  custom: true
113
113
  });
114
114
  if (!res.confirmed) {
@@ -152,7 +152,7 @@ let TroubleshootIssueService = class TroubleshootIssueService extends Disposable
152
152
  return;
153
153
  }
154
154
  const result = await this.askToReproduceIssue(( localize(
155
- 15701,
155
+ 18115,
156
156
  "Issue troubleshooting is active and has temporarily disabled all installed extensions. Check if you can still reproduce the problem and proceed by selecting from these options."
157
157
  )));
158
158
  if (result === "good") {
@@ -170,7 +170,7 @@ let TroubleshootIssueService = class TroubleshootIssueService extends Disposable
170
170
  await this.userDataProfileManagementService.createAndEnterTransientProfile();
171
171
  this.updateState(this.state);
172
172
  const result = await this.askToReproduceIssue(( localize(
173
- 15702,
173
+ 18116,
174
174
  "Issue troubleshooting is active and has temporarily reset your configurations to defaults. Check if you can still reproduce the problem and proceed by selecting from these options."
175
175
  )));
176
176
  if (result === "stop") {
@@ -178,13 +178,13 @@ let TroubleshootIssueService = class TroubleshootIssueService extends Disposable
178
178
  }
179
179
  if (result === "good") {
180
180
  await this.askToReportIssue(( localize(
181
- 15703,
181
+ 18117,
182
182
  "Issue troubleshooting has identified that the issue is caused by your configurations. Please report the issue by exporting your configurations using \"Export Profile\" command and share the file in the issue report."
183
183
  )));
184
184
  }
185
185
  if (result === "bad") {
186
186
  await this.askToReportIssue(( localize(
187
- 15704,
187
+ 18118,
188
188
  "Issue troubleshooting has identified that the issue is with {0}.",
189
189
  this.productService.nameLong
190
190
  )));
@@ -199,15 +199,15 @@ let TroubleshootIssueService = class TroubleshootIssueService extends Disposable
199
199
  askToReproduceIssue(message) {
200
200
  return (new Promise((c, e) => {
201
201
  const goodPrompt = {
202
- label: ( localize(15705, "I Can't Reproduce")),
202
+ label: ( localize(18119, "I Can't Reproduce")),
203
203
  run: () => c("good")
204
204
  };
205
205
  const badPrompt = {
206
- label: ( localize(15706, "I Can Reproduce")),
206
+ label: ( localize(18120, "I Can Reproduce")),
207
207
  run: () => c("bad")
208
208
  };
209
209
  const stop = {
210
- label: ( localize(15707, "Stop")),
210
+ label: ( localize(18121, "Stop")),
211
211
  run: () => c("stop")
212
212
  };
213
213
  this.notificationHandle = this.notificationService.prompt(Severity.Info, message, [goodPrompt, badPrompt, stop], {
@@ -223,9 +223,9 @@ let TroubleshootIssueService = class TroubleshootIssueService extends Disposable
223
223
  if (res === "good") {
224
224
  await this.dialogService.prompt({
225
225
  type: Severity.Info,
226
- message: ( localize(15698, "Troubleshoot Issue")),
226
+ message: ( localize(18112, "Troubleshoot Issue")),
227
227
  detail: ( localize(
228
- 15708,
228
+ 18122,
229
229
  "This likely means that the issue has been addressed already and will be available in an upcoming release. You can safely use {0} insiders until the new stable version is available.",
230
230
  this.productService.nameLong
231
231
  )),
@@ -248,11 +248,11 @@ let TroubleshootIssueService = class TroubleshootIssueService extends Disposable
248
248
  async askToReproduceIssueWithInsiders() {
249
249
  const confirmRes = await this.dialogService.confirm({
250
250
  type: "info",
251
- message: ( localize(15698, "Troubleshoot Issue")),
252
- primaryButton: ( localize(15709, "Download {0} Insiders", this.productService.nameLong)),
253
- cancelButton: ( localize(15710, "Report Issue Anyway")),
251
+ message: ( localize(18112, "Troubleshoot Issue")),
252
+ primaryButton: ( localize(18123, "Download {0} Insiders", this.productService.nameLong)),
253
+ cancelButton: ( localize(18124, "Report Issue Anyway")),
254
254
  detail: ( localize(
255
- 15711,
255
+ 18125,
256
256
  "Please try to download and reproduce the issue in {0} insiders.",
257
257
  this.productService.nameLong
258
258
  )),
@@ -269,20 +269,20 @@ let TroubleshootIssueService = class TroubleshootIssueService extends Disposable
269
269
  }
270
270
  const res = await this.dialogService.prompt({
271
271
  type: "info",
272
- message: ( localize(15698, "Troubleshoot Issue")),
272
+ message: ( localize(18112, "Troubleshoot Issue")),
273
273
  buttons: [{
274
- label: ( localize(15712, "I can't reproduce")),
274
+ label: ( localize(18126, "I can't reproduce")),
275
275
  run: () => "good"
276
276
  }, {
277
- label: ( localize(15713, "I can reproduce")),
277
+ label: ( localize(18127, "I can reproduce")),
278
278
  run: () => "bad"
279
279
  }],
280
280
  cancelButton: {
281
- label: ( localize(15714, "Stop")),
281
+ label: ( localize(18128, "Stop")),
282
282
  run: () => "stop"
283
283
  },
284
284
  detail: ( localize(
285
- 15715,
285
+ 18129,
286
286
  "Please try to reproduce the issue in {0} insiders and confirm if the issue exists there.",
287
287
  this.productService.nameLong
288
288
  )),
@@ -348,7 +348,7 @@ registerAction2(class TroubleshootIssueAction extends Action2 {
348
348
  constructor() {
349
349
  super({
350
350
  id: "workbench.action.troubleshootIssue.start",
351
- title: ( localize2(15716, "Troubleshoot Issue...")),
351
+ title: ( localize2(18130, "Troubleshoot Issue...")),
352
352
  category: Categories.Help,
353
353
  f1: true,
354
354
  precondition: ( ContextKeyExpr.and(( IssueTroubleshootUi.ctxIsTroubleshootActive.negate()), ( RemoteNameContext.isEqualTo("")), ( IsWebContext.negate())))
@@ -362,7 +362,7 @@ registerAction2(class extends Action2 {
362
362
  constructor() {
363
363
  super({
364
364
  id: "workbench.action.troubleshootIssue.stop",
365
- title: ( localize2(15717, "Stop Troubleshoot Issue")),
365
+ title: ( localize2(18131, "Stop Troubleshoot Issue")),
366
366
  category: Categories.Help,
367
367
  f1: true,
368
368
  precondition: IssueTroubleshootUi.ctxIsTroubleshootActive
@@ -81,7 +81,7 @@ let BaseIssueContribution = class BaseIssueContribution extends Disposable {
81
81
  }));
82
82
  const reportIssue = {
83
83
  id: OpenIssueReporterActionId,
84
- title: ( localize2(15718, "Report Issue...")),
84
+ title: ( localize2(18132, "Report Issue...")),
85
85
  category: Categories.Help
86
86
  };
87
87
  this._register(MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
@@ -91,7 +91,7 @@ let BaseIssueContribution = class BaseIssueContribution extends Disposable {
91
91
  group: "3_feedback",
92
92
  command: {
93
93
  id: OpenIssueReporterActionId,
94
- title: ( localize(15719, "Report &&Issue"))
94
+ title: ( localize(18133, "Report &&Issue"))
95
95
  },
96
96
  order: 3
97
97
  }));
@@ -103,3 +103,8 @@ export interface IIssueSubmissionHost {
103
103
  setUploading(uploading: boolean): void;
104
104
  setAttachmentUploadState(index: number, state: "pending" | "uploading" | "done"): void;
105
105
  }
106
+ export interface ISimilarIssue {
107
+ readonly html_url: string;
108
+ readonly title: string;
109
+ readonly state?: string;
110
+ }