Change:
notice that the has a -script run the task manually reload window :bug: the task doesn't start automatically
cc you fixed this in the past
I certainly caused this w the task reconnection - will look into it
this is working for me now - likely fixed with one of my recent PRs related to automatic tasks
Sorry, this doesn't work
you need to allow automatic tasks to run. have you run !
https://user-
https://user-
Why is this now needed? I have trusted this workspace and I have run this exact task successfully in the past?
it's always been needed. if you've ever hit disallow, it won't work. once you've allowed for the folder once, you shouldn't have to again
I doubt that's true. When I hit allow it writes a workspace setting and that wasn't needed, it came in via I have been using this feature years before this change - albeit infrequently in side projects. I already have the - option and I have given trust to the folder. So, why do we put up further hurdles to use this feature?
was to prevent these tasks from running automatically without consent of the user in a workspace that may or may not have been set up /configured by them.
some people can find it jarring and unwanted if they run automatically - even if they trust the workspace and happen to have that in their file
If I'm remembering right there was always an opt-in via notification (maybe requiring engaging with the task system before it shows?). Whether a task runs on startup is a user preference, so instead of a hidden preference stored in local storage, tasks has moved to a setting. Is the problem that there was no migration to the setting?
Yes I think so
Looping in for reference but if I remember correctly this notification was the workaround for the lack of workspace trust. We prompted folks with an FYI to ask them for consent - similar prompts existed for eslint or tsserver and workspace trust is the answer No. This is a workspace configuration file which means "team preference". It is the same as using source maps for debugging or not. Or what typescript version to use etc. Also, the "Manage Automatic Tasks in Folder" writes a workspace setting not a user setting
It was here , derived from this terminal change The discussion in the terminal feature request is here: I did remember some of this wrong after digging into it and it was primarily for security, but it's not the only reason for it now. The UX of this is an important part that was refined over time and carried over to terminal profiles; I have a preference of never wanting a workspace to modify my default terminal profile, regardless of whether I trust it. I disagree, I've always had auto run tasks disabled as I want to control when they run. This was a consideration when the notification was . Source maps are a bad comparison as if they work they're almost always a better experience (though I often disable them to access ran variable names). Yes, we simplified it from opt-in to auto running tasks per workspace as that's handled by workspace trust now, to simply "am I a user who wants to enable auto run tasks?". That seems like it aligns with you wanting to have them always enabled and me wanted to have them always disabled.
I also have many my preferences but the team preferences overrule them: source maps, prettier, lint rules etc pp. That's part of agreeing what are team and personal settings. As a side note: I am not aware that auto tasks have ever been a topic for us (VS Code) and I also don't see any of them in our file. Don't get me wrong: I am happy with a "overrule team decision and go with my preference" path. I think this applies to a few none-critical things, like I want that for source maps. Anyways, the implementation for auto-run task is poor: no migration, essentially breaking the feature the "manage automatic task in folder"-command writes a team/workspace-setting which defeats the purpose of overruling team configuration the default value for is . Its docs say "Prompt for permission for each folder" which is not true and misleading
My initial feeling about this was if the folder is trusted, the tasks should run automatically when configured to do so. Several points I encountered when I raised this were: the manage automatic tasks command has been around for a long time and we didn't want to remove it for those that are used to it The setting would make it easier and more discoverable to manage automatic tasks. I am in favor of removing the prompt per folder and respecting 1) a trusted workspace 2) the setting as configured via the actions or directly. I am also in favor of making this a user setting instead of a workspace/folder specific one.
I like that but the action shouldn't write a workspace-setting because is already a "workspace setting". I would argue this should only be allowed as user-setting (which I believe our settings model supports). Also, the default should be because you conflict team-choice - doing that shouldn't be default. In untrusted workspaces don't ever auto-run a task and maybe show a squiggle in that signals that
Yes I meant as a user setting and agree with you re untrusted workspaces I am in favor of making this a user setting instead of a workspace/folder specific one.
We're bringing this to the UX sync to decide what the right approach is
Proposal: Untrusted: automatic tasks Trusted: based on user setting
Approved in the UX sync
Storage target will now be user and storage scope will be profile

Discussion:
import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { ITaskService, IWorkspaceFolderTaskResult } from 'vs/workbench/contrib/tasks/common/taskService'; import { RunOnOptions, Task, TaskRunSource, TaskSource, TaskSourceKind, TASKS_CATEGORY, WorkspaceFileTaskSource, IWorkspaceTaskSource } from 'vs/workbench/contrib/tasks/common/tasks'; <del> import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; </del> import { IQuickPickItem, IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import { Action2 } from 'vs/platform/actions/common/actions'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IWorkspaceTrustManagementService } from 'vs/platform/workspace/common/workspaceTrust'; import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration'; <del> import { IOpenerService } from 'vs/platform/opener/common/opener'; </del> import { URI } from 'vs/base/common/uri'; import { Event } from 'vs/base/common/event'; import { ILogService } from 'vs/platform/log/common/log'; <del> const HAS_PROMPTED_FOR_AUTOMATIC_TASKS = 'task.hasPromptedForAutomaticTasks'; </del> const ALLOW_AUTOMATIC_TASKS = 'task.allowAutomaticTasks'; export class RunAutomaticTasks extends Disposable implements IWorkbenchContribution {

@ITaskService private readonly _taskService: ITaskService, @IConfigurationService private readonly _configurationService: IConfigurationService, @IWorkspaceTrustManagementService private readonly _workspaceTrustManagementService: IWorkspaceTrustManagementService, <del> @ILogService private readonly _logService: ILogService, @IStorageService private readonly _storageService: IStorageService, @IOpenerService private readonly _openerService: IOpenerService, @INotificationService private readonly _notificationService: INotificationService) { </del> <ins> @ILogService private readonly _logService: ILogService) { </ins> super(); if (this._workspaceTrustManagementService.isWorkspaceTrusted()) { this._tryRunTasks();

} const workspaceTasks = await this._taskService.getWorkspaceTasks(TaskRunSource.FolderOpen); this._logService.trace(`RunAutomaticTasks: Found ${workspaceTasks.size} automatic tasks`); <del> await this._runWithPermission(this._taskService, this._storageService, this._notificationService, this._workspaceTrustManagementService, this._openerService, this._configurationService, workspaceTasks); </del> <ins> await this._runWithPermission(this._taskService, this._configurationService, workspaceTasks); </ins> } private _runTasks(taskService: ITaskService, tasks: Array<Task | Promise<Task | undefined>>) {

return { tasks, taskNames, locations }; } <del> private async _runWithPermission(taskService: ITaskService, storageService: IStorageService, notificationService: INotificationService, workspaceTrustManagementService: IWorkspaceTrustManagementService, openerService: IOpenerService, configurationService: IConfigurationService, workspaceTaskResult: Map<string, IWorkspaceFolderTaskResult>) { </del> <ins> private async _runWithPermission(taskService: ITaskService, configurationService: IConfigurationService, workspaceTaskResult: Map<string, IWorkspaceFolderTaskResult>) { </ins> <del> const hasShownPromptForAutomaticTasks = storageService.getBoolean(HAS_PROMPTED_FOR_AUTOMATIC_TASKS, StorageScope.WORKSPACE, false); const { tasks, taskNames, locations } = this._findAutoTasks(taskService, workspaceTaskResult); </del> <ins> const { tasks, taskNames } = this._findAutoTasks(taskService, workspaceTaskResult); </ins> if (taskNames.length === 0) { return; } <del> if (configurationService.getValue(ALLOW_AUTOMATIC_TASKS) === 'on') { this._runTasks(taskService, tasks); } else if (configurationService.getValue(ALLOW_AUTOMATIC_TASKS) === 'auto' && !hasShownPromptForAutomaticTasks) { // by default, only prompt once per folder // otherwise, this can be configured via the setting this._showPrompt(notificationService, storageService, openerService, configurationService, taskNames, locations).then(allow => { if (allow) { storageService.store(HAS_PROMPTED_FOR_AUTOMATIC_TASKS, true, StorageScope.WORKSPACE, StorageTarget.USER); this._runTasks(taskService, tasks); } }); </del> <ins> if (configurationService.getValue(ALLOW_AUTOMATIC_TASKS) === 'off') { return; </ins> } <del> } private _showPrompt(notificationService: INotificationService, storageService: IStorageService, openerService: IOpenerService, configurationService: IConfigurationService, taskNames: Array<string>, locations: Map<string, URI>): Promise<boolean> { return new Promise<boolean>(resolve => { notificationService.prompt(Severity.Info, nls.localize('tasks.run.allowAutomatic', "This workspace has tasks ({0}) defined ({1}) that run automatically when you open this workspace. Do you allow automatic tasks to run when you open this workspace?", taskNames.join(', '), Array.from(locations.keys()).join(', ') ), [{ label: nls.localize('allow', "Allow and run"), run: () => { resolve(true); configurationService.updateValue(ALLOW_AUTOMATIC_TASKS, 'on', ConfigurationTarget.WORKSPACE); } }, { label: nls.localize('disallow', "Disallow"), run: () => { resolve(false); configurationService.updateValue(ALLOW_AUTOMATIC_TASKS, 'off', ConfigurationTarget.WORKSPACE); } }, { label: locations.size === 1 ? nls.localize('openTask', "Open file") : nls.localize('openTasks', "Open files"), run: async () => { for (const location of locations) { await openerService.open(location[1]); } resolve(false); } }] ); storageService.store(HAS_PROMPTED_FOR_AUTOMATIC_TASKS, true, StorageScope.WORKSPACE, StorageTarget.MACHINE); }); </del> <ins> this._runTasks(taskService, tasks); </ins> } } export class ManageAutomaticTaskRunning extends Action2 { public static readonly ID = 'workbench.action.tasks.manageAutomaticRunning'; <del> public static readonly LABEL = nls.localize('workbench.action.tasks.manageAutomaticRunning', "Manage Automatic Tasks in Folder"); </del> <ins> public static readonly LABEL = nls.localize('workbench.action.tasks.manageAutomaticRunning', "Manage Automatic Tasks"); </ins> constructor() { super({

public async run(accessor: ServicesAccessor): Promise<any> { const quickInputService = accessor.get(IQuickInputService); const configurationService = accessor.get(IConfigurationService); <del> const allowItem: IQuickPickItem = { label: nls.localize('workbench.action.tasks.allowAutomaticTasks', "Allow Automatic Tasks in Folder") }; const disallowItem: IQuickPickItem = { label: nls.localize('workbench.action.tasks.disallowAutomaticTasks', "Disallow Automatic Tasks in Folder") }; </del> <ins> const allowItem: IQuickPickItem = { label: nls.localize('workbench.action.tasks.allowAutomaticTasks', "Allow Automatic Tasks") }; const disallowItem: IQuickPickItem = { label: nls.localize('workbench.action.tasks.disallowAutomaticTasks', "Disallow Automatic Tasks") }; </ins> const value = await quickInputService.pick([allowItem, disallowItem], { canPickMany: false }); if (!value) { return; } <del> configurationService.updateValue(ALLOW_AUTOMATIC_TASKS, value === allowItem ? 'on' : 'off', ConfigurationTarget.WORKSPACE); </del> <ins> configurationService.updateValue(ALLOW_AUTOMATIC_TASKS, value === allowItem ? 'on' : 'off', ConfigurationTarget.USER); </ins> } }

}, [TaskSettingId.AllowAutomaticTasks]: { type: 'string', <del> enum: ['on', 'auto', 'off'], </del> <ins> enum: ['on', 'off'], </ins> enumDescriptions: [ nls.localize('task.allowAutomaticTasks.on', "Always"), <del> nls.localize('task.allowAutomaticTasks.auto', "Prompt for permission for each folder"), </del> nls.localize('task.allowAutomaticTasks.off', "Never"), ], <del> description: nls.localize('task.allowAutomaticTasks', "Enable automatic tasks in the folder - note that tasks won't run in an untrusted workspace."), default: 'auto', </del> <ins> description: nls.localize('task.allowAutomaticTasks', "Enable automatic tasks - note that tasks won't run in an untrusted workspace."), default: 'on', </ins> restricted: true }, [TaskSettingId.ShowDecorations]: {