SLOPSHOPPER

workspaces-attention

Reports confirmed session and subagent completion to the owning VS Code window.

newprocess
A shopper browsing a rack in a slop shop
README

Claude Workspaces

Manage workspace-aware Claude Code sessions across VS Code multi-root workspaces.

Features

  • Start Claude Code in any root of a saved multi-root workspace.
  • Configure directed cross-root imports for each workspace root.
  • Keep multiple live sessions organized in one VS Code panel.
  • Receive a native Windows notification when a background session needs input.
  • Rename supported sessions and resume them from saved metadata.
  • Review each session's root, imported paths, status, and available actions.

Install

Install the stable version of Claude Workspaces from the VS Code Marketplace, or run:

code --install-extension cbeaulieu-gt.vscode-claude-workspaces

To install or switch to the pre-release channel, use the Marketplace action or run:

code --install-extension cbeaulieu-gt.vscode-claude-workspaces --pre-release

After updating, run Developer: Reload Window so the running extension host loads the new version.

See the versioning policy for current channel versions, the release cadence, and source packaging commands.

The extension is available only when VS Code has opened a saved .code-workspace file. It intentionally does not activate in a folder window or an untitled workspace.

Feature tour

Choose which workspace roots each Claude session may import.

Workspace configuration selecting backend and docs as directed imports for frontend

Name your active sessions and resume saved conversations from the sidebar.

Dashboard and Architecture session tabs with API Review and its session ID in the resume list

Work with Claude Code in the embedded terminal, using the selected root and its configured imports.

Running backend Claude Code session summarizing synthetic project data and imported documentation

Configuration

Claude Workspaces stores its configuration in VS Code's workspace-local extension state; it never writes to the .code-workspace file. On first use, and whenever the ordered workspace folder set changes, it prompts for an optional default root, automatic default-root imports, and directed cross-root imports. Dismissing the prompt keeps the first workspace folder as the effective default and disables every cross-root import.

For Claude Code installations that support UUID-backed sessions, the same workspace-local extension state stores resumable-session metadata: the Claude session UUID, display name, original root identity, root label and path, creation time, and last-launch time. Claude Workspaces does not copy or store Claude's transcript contents.

claudeWorkspaces.claudeExecutable is an optional string setting for a Claude executable path or command. Leave it unset to use claude from the extension host's PATH.

claudeWorkspaces.sessionSidebarPosition places the action sidebar on the left or right of the terminal (default: right). Changing it moves the sidebar immediately and preserves its collapsed state and running sessions. Actions stay at the top; resumable sessions appear below and scroll independently. Collapsed buttons show their full action names on hover.

claudeWorkspaces.sessionSidebarInitiallyExpanded defaults to true. Set it to false to start with icon buttons in a new window or newly opened Sessions view. The sidebar toggle controls the current view; changing this preference does not override that choice until a new view opens.

claudeWorkspaces.sessionDetailsInitiallyExpanded controls whether the session details bar starts expanded and defaults to true. The bar shows the launch root and the exact --add-dir paths supplied when the active session launched. The launch root is the directory where the session started, not a live tracker of later cd commands; collapsing the bar does not change the running session.

Waiting-session notifications

Native waiting-session notifications are available only from a local Windows x64 extension host; remote extension hosts are an explicit no-op. A notification is raised only when an unfocused VS Code window receives a permission_prompt, agent_needs_input, or elicitation_dialog hook event. idle_prompt moves a session to idle when no subagent remains active. Confirmed response completion moves it to waiting once background subagents have finished; neither event notifies. A stage opened while its window is focused is already seen, so losing focus later does not fire a notification.

In the live session tabs, a blue-ring working indicator means Claude is working; it remains visible while background subagents run after the parent response ends. It clears after the last subagent finishes unless the parent is still working. A genuine permission or input request takes precedence over background activity. A green dot means a completed response has not been viewed. Selecting that live tab in the visible panel clears the unread response dot but leaves the session waiting. Selected, starting, and closing styles remain independent from both activity indicators.

Attention hooks attempt delivery up to three times on transient file I/O failures. If signal delivery still fails, Claude reports a delivery error; a lost completion signal can leave the working indicator visible until the session closes.

Background-agent activity tracking requires Claude Code 2.1.287 or later and an admitted completion reporter. Claude Workspaces adds its bundled reporter with --plugin-dir, preserving existing plugins and settings. It tracks starts and confirmed turn.complete events together; a blocking SubagentStop or Stop hook does not confirm completion.

Older CLIs can still run ordinary sessions and supported input notifications. When the reporter is unavailable, the extension warns and disables background tracking. Safe mode, disableAllHooks, organization policy, or Anthropic's remote rollout can prevent reporter loading even on a newer CLI. If all hooks are disabled, no activity metadata is available. Anthropic documents that a remote rollout refusal cannot be enabled by a local setting in its mod availability troubleshooting guide.

The Claude Workspaces panel tab badge counts every live session waiting for input, including responses that have already been viewed. It disappears when no live session is waiting.

The toast names the workspace and managed session. Selecting it reveals the Claude Workspaces panel in the existing owner window and activates the correlated live session without opening another VS Code window. On Windows, the owning VS Code taskbar entry may highlight or flash; native notifications cannot guarantee programmatic foreground activation. Selecting a stale toast after its session or owner window closes is a no-op and does not open an empty window.

claudeWorkspaces.waitingSessionNotifications defaults to true and controls native Windows notifications. Its value is read for each newly opened waiting stage, so a setting change applies without reloading VS Code. Disabling it does not disable hook ingestion or session activity tracking. Waiting detection also requires a Claude Code version that supports --settings. If CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1 strips the hook routing variables, no Claude Workspaces Output diagnostic is expected. Notification ignores hook stderr; after the first UserPromptSubmit, the managed Claude session instead shows a non-blocking hook-error notice beginning Claude Workspaces attention hook failed: Attention channel environment is unavailable. See the env-scrub runbook.

Commands and sessions

The Claude Workspaces panel and Command Palette provide New Session, New in Folder, Close Session, Restart Fresh, Previous/Next Session, and Configure Workspace. Sessions are owned only by this extension: closing or deactivating the extension terminates its managed Claude processes without changing VS Code terminals or externally launched Claude processes. Saved conversations appear in the panel's separate Resume sessions list after their live process closes. Opening and closing a session without sending a prompt does not create a saved conversation, so it stays out of the list. Retry and Restart Fresh always resolve the current workspace configuration before launching.

Run Claude Workspaces: Show Claude Workspaces from the Command Palette to reveal the panel and focus its Sessions view. The command has no default shortcut. To assign one, open Preferences: Open Keyboard Shortcuts, search for Show Claude Workspaces, and choose your preferred key combination.

Right-click a session tab and choose Rename Session… to give that live session a custom display name. Choose Close Session to close that specific live session. The menu is also available with Shift+F10 or the Menu key while the tab is focused. Renames are saved for UUID-backed sessions and reused when those sessions resume. Restart Fresh creates a separate new session with the normal generated name.

Choose a saved entry under Resume sessions to reopen it in its original workspace root. Before launching, Claude Workspaces verifies that the root is still present at the exact saved path and resolves the current executable, cross-root imports, and filesystem availability. A UUID already represented by a live managed session is hidden from the resume list and cannot be launched a second time.

Each entry shows its full Claude session ID and a relative Last opened time beneath its name, so similarly named or older conversations remain distinguishable. The relative value refreshes while the panel stays open; hover the entry to see the exact launch time in your local timezone.

Right-click an entry under Resume sessions and choose Forget Session to remove its saved metadata. With the entry focused, Shift+F10 or the Menu key opens the same menu. Forgetting removes the entry from this workspace’s resume list; it does not delete Claude transcripts or stop another session.

Forget Session is also available from failed-resume notifications. If the saved root is missing or has changed, the notification also offers Start New and Configure Workspace…. If Claude rejects a stale session, it instead offers Start New and Open Logs. Dismissing either notification keeps the saved metadata.

HTTP and HTTPS links in session output can be opened through VS Code with Ctrl+click on Windows/Linux or Cmd+click on macOS. A regular click remains available for terminal text selection.

Use Configure Workspace… to select an optional default root, choose whether other folders automatically include it, and select directed cross-root imports. Automatically include the default root is enabled for newly configured workspaces. Use only selected imports disables that convenience default; explicitly selected imports still apply. Existing saved configurations migrate with automatic imports disabled and their directed imports preserved.

Automatic imports follow the current effective default root, including the first available folder when the configured override is unavailable. Sessions started in that root do not import themselves, and explicitly selecting the default root does not add it twice. The automatic policy is stored separately from directed imports, so switching it off leaves those selections intact.

Reopening the command highlights the saved default root and automatic-import option and checks each saved import that is still part of the workspace, so you can adjust the current configuration instead of rebuilding it. Cancelling any picker keeps the previously saved configuration unchanged. A launch starts Claude in its selected root and passes each enabled available import as a separate --add-dir argument.

V1 limitations

V1 is session-oriented rather than a general terminal or a Claude conversation client. It does not reconnect to a still-running process, adopt externally launched Claude sessions, run outside a saved workspace, or provide general-purpose terminal features. Resumption is available only when the configured Claude executable advertises both --session-id and --resume; if either flag is unavailable, or if the capability probe errors or times out, new sessions still launch normally but do not create resumable metadata.

Claude owns transcript storage, retention, and cleanup. Claude Workspaces neither inspects nor deletes those transcript files, so saved metadata can outlive the Claude transcript it identifies. See Claude Code's session documentation for the transcript lifecycle.

Workspace-level CLAUDE.md configuration and shared skill discovery are future scope, not current features.

Claude Code IDE integration can switch panels

When a Claude Workspaces session is connected to the official Claude Code IDE integration in VS Code, editing an existing file can open a diff and switch the active panel to the integrated Terminal. The upstream IDE integration reveals the Terminal after opening the diff; this is not caused by Claude Workspaces' notification hooks. See the confirmed reproduction.

This is a known limitation when keeping the Claude IDE integration enabled. Claude Workspaces has no supported way to prevent that upstream panel switch while preserving the IDE connection. Disabling the connection also removes its IDE features, so it is not a fix that preserves the integration.

To return, select the Claude Workspaces panel or run Claude Workspaces: Show Claude Workspaces from the Command Palette. Intentional navigation to the Terminal remains available.

Runtime requirements

  • Windows x64
  • VS Code 1.120.0 or later
  • Claude Code installed and available on the VS Code extension host PATH, or configured with claudeWorkspaces.claudeExecutable

Development prerequisites

  • Node.js 24 (recommended)
  • npm

Troubleshooting

  • Save the workspace as a .code-workspace file before using the commands or panel.
  • Verify that claude is available on the VS Code extension host PATH, or set claudeWorkspaces.claudeExecutable to the executable path or command. Paths containing spaces are supported.
  • Use Configure Workspace… after workspace roots change or when a launch skips unavailable local or network import roots.
  • If a saved root was removed, renamed, or moved, choose Start New to launch from the current default configuration, Forget Session to remove its saved metadata, or Configure Workspace… to review roots and imports.
  • If Claude rejects a saved UUID after its transcript was cleaned up, choose Start New, Forget Session, or Open Logs. Closing the notification leaves the saved metadata unchanged.
  • If no Resume sessions entries appear, run claude --help using the same executable configured for the extension and confirm that it lists both --session-id and --resume. A failed or timed-out help probe also skips resumable metadata, but it does not block normal new-session launches.
  • If Claude exits immediately or fails to start, use the notification's Retry or Open Logs action to inspect the Claude Workspaces output.

Diagnostic logging

To inspect extension diagnostics, open View: Output and select the Claude Workspaces Output channel. Set claudeWorkspaces.logLevel to one of off, error, warn, info, debug, or trace; it defaults to info. error shows failures, warn adds recoverable conditions, and info adds the normal extension lifecycle. Use debug or trace to gather more detailed diagnostics, then return to info when finished. Changes apply immediately; you do not need to reload VS Code or recreate a session.

The channel never logs Claude prompts, responses, terminal traffic, environment values, or sensitive carrier arguments.

For an activity indicator problem, run Claude Workspaces: Capture Activity Diagnostics from the Command Palette before reproducing it. The command opens the Output channel and temporarily records activity events, hashed correlation IDs, agent counts, and state changes, even when regular logging is off. Run it again to stop. Capture stops automatically after five minutes or 256 events, and on extension shutdown; it does not change your settings. Share only lines marked "diagnostic":"activity" from that capture.

Development

See CONTRIBUTING.md for setup, validation, pull request, and documentation guidance.

Publishing

Pushing a vMAJOR.MINOR.PATCH tag runs the Publish workflow. The workflow verifies that the tag matches package.json, derives the channel from the version, runs the full validation suite, packages and publishes the Windows x64 VSIX, and creates or updates the matching GitHub Release from CHANGELOG.md. Odd minor versions publish as pre-releases; even minor versions publish as stable releases.

New features integrate through a versioned pre-release branch. Stable candidates promote approved work from that line to main. See the versioning policy for active branch names, selective and full promotion, source provenance, and forward-porting rules.

The repository must provide an Actions secret named VSCE_PAT containing an Azure DevOps personal access token with All accessible organizations access and Marketplace (Manage) scope for the cbeaulieu-gt publisher. See the VS Code publishing documentation for token creation and Marketplace prerequisites.

To retry an existing tag without moving it, open Actions → Publish → Run workflow and enter the tag. The same validation and publication sequence runs against that immutable tag.

Source 1 files
hooks/register.js 66 lines
1// Metadata only: never send answers, prompts, transcripts, or tool results.
2async function logFailure($) {
3  try {
4    await $.ui.log("Claude Workspaces attention signal delivery failed.");
5  } catch {
6    // Diagnostics are best effort too, including asynchronous log failures.
7  }
8}
9
10async function publish($, fields) {
11  try {
12    const sessionId = await $.session.id();
13    const result = await $.process.run([
14      "powershell.exe", "-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass",
15      "-File", `${$.plugin.root}/report-activity.ps1`
16    ], {
17      stdin: JSON.stringify({ session_id: sessionId, completion_reporter_ready: true, ...fields }),
18      timeoutMs: 5000
19    });
20    if (result.exitCode === 0) {
21      return;
22    }
23  } catch {
24    // Delivery failures must never change another plugin's decision or result.
25  }
26  await logFailure($);
27}
28
29async function markReady($, ended = false) {
30  try {
31    await $.env.set("CLAUDE_WORKSPACES_COMPLETION_SESSION", ended ? "" : await $.session.id());
32  } catch {
33    await logFailure($);
34  }
35}
36
37export function register(on) {
38  on("session.start", async ($, e, next) => {
39    await markReady($);
40    return next(e);
41  });
42  // SessionStart also covers /clear and /resume within an already-loaded worker.
43  on("classic.SessionStart", async ($, e, next) => {
44    await markReady($);
45    return next(e);
46  });
47  on("session.end", async ($, e, next) => {
48    await markReady($, true);
49    return next(e);
50  });
51  on("classic.SubagentStart", async ($, e, next) => {
52    await publish($, {
53      hook_event_name: "SubagentStart", agent_id: e.agent_id
54    });
55    return next(e);
56  });
57  on("turn.complete", async ($, e, next) => {
58    const result = await next(e);
59    await publish($, {
60      hook_event_name: "TurnComplete", completion_reason: e.reason, is_aborted: e.isAborted,
61      ...(e.agentId === undefined ? {} : { agent_id: e.agentId })
62    });
63    return result;
64  });
65}
66