From 1fd8ee783974fe1dfb48ce2406deed9f2175b5c0 Mon Sep 17 00:00:00 2001 From: Ehab Younes Date: Thu, 6 Aug 2026 14:33:29 +0300 Subject: [PATCH] feat: deprecate the Tasks panel and hide it on Coder 2.35 and above Coder Tasks was deprecated in June 2026 and is removed from deployments starting v2.37, replaced by Coder Agents. Mark the activity bar item as deprecated and only show the panel on deployments that predate the deprecation (2.34 and below), gated by a new coder.tasksSupported context set from the deployment version after login. --- package.json | 6 +++--- src/core/contextManager.ts | 1 + src/extension.ts | 28 +++++++++++++++++++++++++--- src/featureSet.ts | 8 ++++++++ test/unit/featureSet.test.ts | 16 +++++++++++++++- 5 files changed, 52 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index e534270e7b..0c3e97201e 100644 --- a/package.json +++ b/package.json @@ -313,7 +313,7 @@ }, { "id": "coderTasks", - "title": "Coder Tasks", + "title": "Coder Tasks (Deprecated)", "icon": "media/tasks-logo.svg" }, { @@ -354,14 +354,14 @@ "id": "coder.tasksLogin", "name": "Coder Tasks", "icon": "media/tasks-logo.svg", - "when": "!coder.authenticated" + "when": "!coder.authenticated && coder.tasksSupported" }, { "type": "webview", "id": "coder.tasksPanel", "name": "Coder Tasks", "icon": "media/tasks-logo.svg", - "when": "coder.authenticated" + "when": "coder.authenticated && coder.tasksSupported" } ], "coderExperimentalWorkspaces": [ diff --git a/src/core/contextManager.ts b/src/core/contextManager.ts index 7e57abd6fb..39217a6f8b 100644 --- a/src/core/contextManager.ts +++ b/src/core/contextManager.ts @@ -5,6 +5,7 @@ const CONTEXT_DEFAULTS = { "coder.isOwner": false, "coder.loaded": false, "coder.sharedWorkspacesSupported": true, + "coder.tasksSupported": false, "coder.workspace.connected": false, "coder.workspace.updatable": false, "coder.workspacesPanelEnabled": false, diff --git a/src/extension.ts b/src/extension.ts index 6dc82209e0..55f9786042 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -4,6 +4,7 @@ import axios, { isAxiosError } from "axios"; import { getErrorMessage } from "coder/site/src/api/errors"; import { createRequire } from "node:module"; import * as path from "node:path"; +import * as semver from "semver"; import * as vscode from "vscode"; import { AnnouncementManager } from "./announcements/manager"; @@ -15,6 +16,7 @@ import { ServiceContainer } from "./core/container"; import { DeploymentManager } from "./deployment/deploymentManager"; import { CertificateError } from "./error/certificateError"; import { getErrorDetail, toError } from "./error/errorUtils"; +import { tasksSupported } from "./featureSet"; import { ActivationTelemetry, type ActivationTracer, @@ -202,12 +204,32 @@ async function doActivate( ); ctx.subscriptions.push(sharedWorkspacesProvider); + // The deprecated Tasks panel only shows on deployments old enough to + // still support it, which requires fetching the deployment version. + const updateTasksSupported = async () => { + let supported = false; + if (deploymentManager.session.current.kind === "signedIn") { + try { + const buildInfo = await client.getBuildInfo(); + supported = tasksSupported(semver.parse(buildInfo.version)); + } catch (error) { + output.warn( + "Unable to fetch deployment version for Tasks panel", + error, + ); + } + } + contextManager.set("coder.tasksSupported", supported); + }; + void updateTasksSupported(); + // Re-probe support on session change (login, logout, deployment switch); // the next fetch clears the message again if still unsupported. ctx.subscriptions.push( - deploymentManager.session.onDidChange(() => - contextManager.set("coder.sharedWorkspacesSupported", true), - ), + deploymentManager.session.onDidChange(() => { + contextManager.set("coder.sharedWorkspacesSupported", true); + void updateTasksSupported(); + }), ); // createTreeView, unlike registerTreeDataProvider, gives us the tree view API diff --git a/src/featureSet.ts b/src/featureSet.ts index 2a209076eb..1f8d53e52d 100644 --- a/src/featureSet.ts +++ b/src/featureSet.ts @@ -26,6 +26,14 @@ function versionAtLeast( return version.compare(minVersion) >= 0 || version.prerelease[0] === "devel"; } +/** + * True when the deployment predates the June 2026 Tasks deprecation + * (2.34 and below). The deprecated Tasks panel is hidden everywhere else. + */ +export function tasksSupported(version: semver.SemVer | null): boolean { + return version !== null && !versionAtLeast(version, "2.35.0"); +} + /** * Builds and returns a FeatureSet object for a given coder version. */ diff --git a/test/unit/featureSet.test.ts b/test/unit/featureSet.test.ts index d8d91637f6..ccfd508065 100644 --- a/test/unit/featureSet.test.ts +++ b/test/unit/featureSet.test.ts @@ -1,7 +1,11 @@ import * as semver from "semver"; import { describe, expect, it } from "vitest"; -import { type FeatureSet, featureSetForVersion } from "@/featureSet"; +import { + type FeatureSet, + featureSetForVersion, + tasksSupported, +} from "@/featureSet"; function expectFlag( flag: keyof FeatureSet, @@ -66,6 +70,16 @@ describe("check version support", () => { ["v2.36.0", "v2.36.1", "v2.37.0", "v3.0.0"], ); }); + it("tasks panel only on deployments before deprecation", () => { + for (const v of ["v2.34.0", "v2.34.7+e491217", "v2.0.0"]) { + expect(tasksSupported(semver.parse(v)), v).toBe(true); + } + for (const v of ["v2.35.0", "v2.36.1", "v3.0.0", "v2.36.0-devel+abc123"]) { + expect(tasksSupported(semver.parse(v)), v).toBe(false); + } + expect(tasksSupported(null)).toBe(false); + }); + it("enables all features for development builds", () => { const featureSet = featureSetForVersion( semver.parse("v0.0.0-devel+abc123"),