src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts/AbstractTaskService/runConfigureTasks
class AbstractTaskService:	private async runConfigureTasks(): Promise<void> {
		if (!(await this.trust())) {
			return;
		}

		if (!this.canRunCommand()) {
			return undefined;
		}
		let taskPromise: Promise<TaskMap>;
		if (this.schemaVersion === JsonSchemaVersion.V2_0_0) {
			taskPromise = this.getGroupedTasks();
		} else {
			taskPromise = Promise.resolve(new TaskMap());
		}

		let stats = this.contextService.getWorkspace().folders.map<Promise<IFileStatWithPartialMetadata | undefined>>((folder) => {
			return this.fileService.stat(folder.toResource('.vscode/tasks.json')).then(stat => stat, () => undefined);
		});

		let createLabel = nls.localize('TaskService.createJsonFile', 'Create tasks.json file from template');
		let openLabel = nls.localize('TaskService.openJsonFile', 'Open tasks.json file');
		const tokenSource = new CancellationTokenSource();
		const cancellationToken: CancellationToken = tokenSource.token;
		let entries = Promise.all(stats).then((stats) => {
			return taskPromise.then((taskMap) => {
				let entries: QuickPickInput<TaskQuickPickEntryType>[] = [];
				let configuredCount = 0;
				let tasks = taskMap.all();
				if (tasks.length > 0) {
					tasks = tasks.sort((a, b) => a._label.localeCompare(b._label));
					for (let task of tasks) {
						entries.push({ label: task._label, task, description: this.getTaskDescription(task), detail: this.showDetail() ? task.configurationProperties.detail : undefined });
						if (!ContributedTask.is(task)) {
							configuredCount++;
						}
					}
				}
				const needsCreateOrOpen = (configuredCount === 0);
				// If the only configured tasks are user tasks, then we should also show the option to create from a template.
				if (needsCreateOrOpen || (taskMap.get(USER_TASKS_GROUP_KEY).length === configuredCount)) {
					let label = stats[0] !== undefined ? openLabel : createLabel;
					if (entries.length) {
						entries.push({ type: 'separator' });
					}
					entries.push({ label, folder: this.contextService.getWorkspace().folders[0] });
				}
				if ((entries.length === 1) && !needsCreateOrOpen) {
					tokenSource.cancel();
				}
				return entries;
			});
		});

		const timeout: boolean = await Promise.race([new Promise<boolean>((resolve) => {
			entries.then(() => resolve(false));
		}), new Promise<boolean>((resolve) => {
			const timer = setTimeout(() => {
				clearTimeout(timer);
				resolve(true);
			}, 200);
		})]);

		if (!timeout && ((await entries).length === 1) && this.configurationService.getValue<boolean>(QUICKOPEN_SKIP_CONFIG)) {
			const entry: any = <any>((await entries)[0]);
			if (entry.task) {
				this.handleSelection(entry);
				return;
			}
		}

		const entriesWithSettings = entries.then(resolvedEntries => {
			resolvedEntries.push(...TaskQuickPick.allSettingEntries(this.configurationService));
			return resolvedEntries;
		});

		this.quickInputService.pick(entriesWithSettings,
			{ placeHolder: nls.localize('TaskService.pickTask', 'Select a task to configure') }, cancellationToken).
			then(async (selection) => {
				if (cancellationToken.isCancellationRequested) {
					// canceled when there's only one task
					const task = (await entries)[0];
					if ((<any>task).task) {
						selection = <TaskQuickPickEntryType>task;
					}
				}
				this.handleSelection(selection);
			});
	}