Skip to content

feat: add Claude workspace management#4

Open
benmarte wants to merge 22 commits intocordwainersmith:masterfrom
benmarte:feature/claude-profiles
Open

feat: add Claude workspace management#4
benmarte wants to merge 22 commits intocordwainersmith:masterfrom
benmarte:feature/claude-profiles

Conversation

@benmarte
Copy link
Copy Markdown

@benmarte benmarte commented Apr 4, 2026

Summary

  • Adds a Workspace model and WorkspaceManager service that persists named workspaces (name + ~/.claude-style directory path) to UserDefaults
  • SessionStore hot-swaps all services when the active workspace changes — no restart required
  • New Workspaces settings section (add / edit / delete / activate) with inline validation and error feedback
  • Menu bar popover workspace switcher showing the active workspace name with a dropdown to switch or jump to Manage Workspaces in settings
  • Workspace switcher in the app sidebar (visible on all screens) with Workspace: [name] label and native dropdown
  • Loading overlay on workspace switch in the full window — prevents interaction with stale data
  • Contextual loading message (Loading [workspace name]…) in the menu bar popover during workspace switch

Screenshots

Settings → Workspaces

image

Workspace Switcher — App Sidebar

image

Workspace Switcher — Menu Bar Toolbar Widget

image

Workspace Example 1

image

Workspace Example 2

image

Test Plan

  • Create a second workspace pointing to a different ~/.claude-* directory
  • Switch workspaces from the menu bar popover — verify sessions/analytics reload with loading overlay
  • Switch workspaces from the sidebar dropdown — verify same live-reload and loading state
  • Switch workspaces from Settings → Workspaces → Activate — verify same live-reload
  • Edit a workspace name/path — verify changes persist across app restarts
  • Delete a workspace — verify the last workspace cannot be deleted
  • Verify the active workspace indicator tracks correctly in both the sidebar and menu bar picker

🤖 Generated with Claude Code

benmarte and others added 16 commits April 4, 2026 14:38
Renamed existing ClaudeProfile in ConfigModels to ClaudeAccountProfile
to avoid collision, then introduced the new ClaudeProfile struct
(Codable, Identifiable, Equatable) as a named pointer to a Claude
config directory for the profiles feature.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ProfileManager

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…on profile switch

- SessionStore.init now requires ProfileManager; claudeDir derived from activeProfile.path
- Added reloadForProfile(_:) to swap watcher/services and re-scan on profile change
- Temporary ClaudoscopeApp.swift fix to pass ProfileManager at init (Task 4 will wire this properly)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace unsafe MainActor.assumeIsolated with @mainactor init(), inject
ProfileManager into MenuBarExtra and full-window environments.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ofile switch

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… change

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…le row

- Only close profile picker when profileManager.activate() returns true
- Disable the already-active profile row to prevent unnecessary session reloads
- Replace Image(systemName: "") placeholder with Color.clear in a Group for proper layout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…chain

- Replace hardcoded ~/.claude/settings.json banner with dynamic path from store.claudeDir
- Reset selectedSession, isLoading, lintResultsValid, plans, and timelineEntries at the start of reloadForProfile to prevent stale state on profile switch
- Remove redundant .receive(on: DispatchQueue.main) from activeProfileChanged subscription since the Task @mainactor already ensures main-actor execution
- ProfileManager.save() structure verified correct — no fix needed
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
benmarte and others added 6 commits April 5, 2026 12:02
…ces settings panel

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add workspace switcher row at top of sidebar (all screens) with
  "Workspace: [name]" label + native menu dropdown
- Add WorkspaceLoadingOverlay to full window when store.isLoading,
  showing "Loading workspace" + workspace name with material blur
- Pass workspace name to LoadingLogoView in popover for contextual
  loading message on workspace switch

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ager

- Rename model file ClaudeProfile.swift → Workspace.swift
- Rename service file ProfileManager.swift → WorkspaceManager.swift
- Rename all type references: ClaudeProfile→Workspace, ProfileManager→WorkspaceManager
- Rename properties: activeProfile→activeWorkspace, profiles→workspaces
- Rename publisher: activeProfileChanged→activeWorkspaceChanged
- Rename method: reloadForProfile→reloadForWorkspace
- Update all local variable names (loop vars, params) throughout views and store
- Aligns naming with feature/llm-agnostic branch for easier future merge

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@benmarte benmarte changed the title feat: add Claude profile management feat: add Claude workspace management Apr 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant