feat(workspaces): IPC API and extension-side data layer for the panel - #1099
Open
EhabY wants to merge 2 commits into
Open
feat(workspaces): IPC API and extension-side data layer for the panel#1099EhabY wants to merge 2 commits into
EhabY wants to merge 2 commits into
Conversation
EhabY
force-pushed
the
ehab/devex-622-workspaces-ipc-api-extension-side-provider-with-data-layer
branch
11 times, most recently
from
August 26, 2026 20:27
8b0ad5e to
a17482e
Compare
Adds the typed IPC contract for the experimental Workspaces panel and the extension-side provider that owns its data, porting the tree views' behaviors to push through IPC. `packages/shared/src/workspaces` defines the contract: `stateUpdated` out; `ready`, `openWorkspace`, `viewInDashboard`, `refresh`, `setFilter` and `watchAgents` back. State is pushed as one update carrying only the fields that changed, and the payloads carry decisions rather than facts to derive, so the webview holds no data and applies no policy: it asks for the state with `ready` and renders what arrives. `WorkspaceStore` lists the active filter while visible, backs off on failures, watches metadata for the agents the panel is showing, and reports what changed. A cancellation token per fetch drops superseded results, the list is pushed before sockets open, and a structural diff keeps quiet polls off the wire. Filters that a deployment rejects stop being offered. Split by concern, in their own layers: - `src/workspace/agentMetadataTracker.ts`: the watched set and its sockets, which linger briefly after release so toggling a row reuses them - `src/workspace/filters.ts`: each filter's query, presentation, role requirement and poll policy, shared with the tree views instead of duplicated `isOwner(user)` moved to `src/api/api-helper.ts` for both `deploymentManager` and the panel, since the `coder.isOwner` context is written after the session change fires. Existing tree views are untouched. The webview's placeholder App prints the pushed state; the UI lands with the tree components.
EhabY
force-pushed
the
ehab/devex-622-workspaces-ipc-api-extension-side-provider-with-data-layer
branch
from
August 26, 2026 20:36
a17482e to
5ae7bef
Compare
…ew mock - Drop WorkspacesPanelProvider.refresh() and its onDidChangeCurrentDeployment listener: every path that event covers already flows through the session store, which the store listens to - Collapse the options-bag constructor into Object.assign so handlers keep reading this.store etc. directly - Replace AgentMetadataTracker's single-knob options object with a lingerMs parameter - Remove the dead disposed guard in handleSessionChange; the session subscription is disposed synchronously - Promote the mock WebviewView into testHelpers.createMockWebviewView and reuse it from the tasks and workspaces test harnesses
EhabY
marked this pull request as ready for review
August 27, 2026 18:01
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes DEVEX-622.
Extension side of the new Workspaces view, behind
coder.experimental.workspacesPanel. No UI yet: the panel prints the pushed state so the data flow can be verified, and the tree component library lands separately.The contract
packages/shared/src/workspaces/holds the typed API both sides import:types.tsfor every type,api.tsfor the messages.stateUpdatedready,openWorkspace,viewInDashboard,refresh,setFilter,watchAgentsOne notification carries only the fields that changed, so two changes land as one message and one render. Payloads carry decisions, not facts to derive:
capabilitieslists the filters the user may select, so the webview applies no owner or deployment-support rulesloading, true only for fetches someone waits on (first list, filter switch, deliberate refresh), never for a poll, so nothing flickersloadingtoo, so an expanded row can tell "waiting on the socket" from "this agent reports no metadata"readyreplays the whole state, so a webview that just loaded (or reloaded) needs no data of its own.The data layer
WorkspaceStorelists the active filter while visible and reports what changed. Oneupdate()records the change, diffs the state structurally, and pushes only the fields the webview lacks. Ported from the tree views: polling stops while hidden, exponential backoff, per-agent metadata over SSE, owner gating, and the HTTP 400 signal that a deployment predates a filter's query. Differences, all in the data layer: aCancellationTokenSourceper fetch replaces the tree's pending-fetch bookkeeping, sockets open only for agents the webview reports as showing (and linger briefly after release, so re-expanding is instant), only cheap filters keep polling, and the list is pushed before sockets open.Failures each have one owner: a failed fetch clears the list and retries with backoff, a rejected query becomes an unavailable filter, a metadata socket reports against its agent only, and user actions surface in a dialog.
loadcannot reject into a timer callback.Split by concern:
agentMetadataTracker.tsowns the watched set and its sockets,filters.tsowns each filter's query, role requirement and poll policy (shared with the tree views), andisOwner(user)moved toapi-helper.tsfor bothdeploymentManagerand the panel.Size
~950 lines of production code (panel, store, tracker, shared contract, wiring) and ~1350 of tests and mocks.
Notes for review
Workspace[], metadata maps) rather than tree nodes, same as the Tasks panel'sTask[]: label, status and sort decisions stay in the webview.extension.ts: every session change (same window or cross window) flows through the session store, whichWorkspaceStorealready listens to.WebviewViewnow lives intest/mocks/testHelpers.tsascreateMockWebviewView, shared with the Tasks panel test.