diff --git a/ui/src/components/account/create-auth-profile-dialog.tsx b/ui/src/components/account/create-auth-profile-dialog.tsx
index 51b7b997..9a04b4cd 100644
--- a/ui/src/components/account/create-auth-profile-dialog.tsx
+++ b/ui/src/components/account/create-auth-profile-dialog.tsx
@@ -32,7 +32,7 @@ export function CreateAuthProfileDialog({ open, onClose }: CreateAuthProfileDial
// Validate profile name: alphanumeric, dash, underscore only
const isValidName = /^[a-zA-Z][a-zA-Z0-9_-]*$/.test(profileName);
- const normalizedGroup = contextGroup.trim().toLowerCase();
+ const normalizedGroup = contextGroup.trim().toLowerCase().replace(/\s+/g, '-');
const isValidContextGroup =
normalizedGroup.length === 0 ||
(normalizedGroup.length <= MAX_CONTEXT_GROUP_LENGTH &&
@@ -73,7 +73,8 @@ export function CreateAuthProfileDialog({ open, onClose }: CreateAuthProfileDial
Create New Account
- Auth profiles require Claude CLI login. Run the command below in your terminal.
+ Auth profiles require Claude CLI login. Run the command below in your terminal. You can
+ edit context mode/group later from the Accounts table.
@@ -118,7 +119,7 @@ export function CreateAuthProfileDialog({ open, onClose }: CreateAuthProfileDial
autoComplete="off"
/>
- Leave empty to use the default shared group.
+ Leave empty to use the default shared group. Spaces are normalized to dashes.
{contextGroup.trim().length > 0 && !isValidContextGroup && (
diff --git a/ui/src/components/account/edit-account-context-dialog.tsx b/ui/src/components/account/edit-account-context-dialog.tsx
new file mode 100644
index 00000000..cd6230c2
--- /dev/null
+++ b/ui/src/components/account/edit-account-context-dialog.tsx
@@ -0,0 +1,139 @@
+import { useMemo, useState } from 'react';
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+} from '@/components/ui/dialog';
+import { Button } from '@/components/ui/button';
+import { Input } from '@/components/ui/input';
+import { Label } from '@/components/ui/label';
+import {
+ Select,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from '@/components/ui/select';
+import type { Account } from '@/lib/api-client';
+import { useUpdateAccountContext } from '@/hooks/use-accounts';
+
+type ContextMode = 'isolated' | 'shared';
+
+const MAX_CONTEXT_GROUP_LENGTH = 64;
+const CONTEXT_GROUP_PATTERN = /^[a-zA-Z][a-zA-Z0-9_-]*$/;
+
+interface EditAccountContextDialogProps {
+ account: Account;
+ onClose: () => void;
+}
+
+export function EditAccountContextDialog({ account, onClose }: EditAccountContextDialogProps) {
+ const updateContextMutation = useUpdateAccountContext();
+ const [mode, setMode] = useState(
+ account.context_mode === 'shared' ? 'shared' : 'isolated'
+ );
+ const [group, setGroup] = useState(account.context_group || 'default');
+
+ const normalizedGroup = useMemo(() => group.trim().toLowerCase().replace(/\s+/g, '-'), [group]);
+ const isSharedGroupValid =
+ normalizedGroup.length > 0 &&
+ normalizedGroup.length <= MAX_CONTEXT_GROUP_LENGTH &&
+ CONTEXT_GROUP_PATTERN.test(normalizedGroup);
+ const canSubmit = mode === 'isolated' || isSharedGroupValid;
+
+ const handleSave = () => {
+ if (!canSubmit) {
+ return;
+ }
+
+ updateContextMutation.mutate(
+ {
+ name: account.name,
+ context_mode: mode,
+ context_group: mode === 'shared' ? normalizedGroup : undefined,
+ },
+ {
+ onSuccess: () => {
+ onClose();
+ },
+ }
+ );
+ };
+
+ const handleOpenChange = (nextOpen: boolean) => {
+ if (!nextOpen) {
+ onClose();
+ }
+ };
+
+ return (
+
+ );
+}
diff --git a/ui/src/components/account/index.ts b/ui/src/components/account/index.ts
index 0b75ccb8..fe6da6ea 100644
--- a/ui/src/components/account/index.ts
+++ b/ui/src/components/account/index.ts
@@ -6,6 +6,7 @@
export { AccountsTable } from './accounts-table';
export { AddAccountDialog } from './add-account-dialog';
export { CreateAuthProfileDialog } from './create-auth-profile-dialog';
+export { EditAccountContextDialog } from './edit-account-context-dialog';
// Flow visualization (from subdirectory)
export { AccountFlowViz } from './flow-viz';
diff --git a/ui/src/hooks/use-accounts.ts b/ui/src/hooks/use-accounts.ts
index b46691af..1e616022 100644
--- a/ui/src/hooks/use-accounts.ts
+++ b/ui/src/hooks/use-accounts.ts
@@ -1,5 +1,5 @@
/**
- * React Query hooks for accounts (profiles.json)
+ * React Query hooks for account management
* Dashboard parity: Full CRUD operations for auth profiles
*/
@@ -58,3 +58,30 @@ export function useDeleteAccount() {
},
});
}
+
+export function useUpdateAccountContext() {
+ const queryClient = useQueryClient();
+
+ return useMutation({
+ mutationFn: ({
+ name,
+ context_mode,
+ context_group,
+ }: {
+ name: string;
+ context_mode: 'isolated' | 'shared';
+ context_group?: string;
+ }) => api.accounts.updateContext(name, { context_mode, context_group }),
+ onSuccess: (_data, vars) => {
+ queryClient.invalidateQueries({ queryKey: ['accounts'] });
+ const contextSummary =
+ vars.context_mode === 'shared'
+ ? `shared (${(vars.context_group || 'default').trim().toLowerCase().replace(/\s+/g, '-')})`
+ : 'isolated';
+ toast.success(`Updated "${vars.name}" context to ${contextSummary}`);
+ },
+ onError: (error: Error) => {
+ toast.error(error.message);
+ },
+ });
+}
diff --git a/ui/src/lib/api-client.ts b/ui/src/lib/api-client.ts
index 12ec590e..bab3455e 100644
--- a/ui/src/lib/api-client.ts
+++ b/ui/src/lib/api-client.ts
@@ -457,6 +457,11 @@ export interface Account {
context_group?: string;
}
+export interface UpdateAccountContext {
+ context_mode: 'isolated' | 'shared';
+ context_group?: string;
+}
+
// Unified config types
export interface ConfigFormat {
format: 'yaml' | 'json' | 'none';
@@ -785,6 +790,11 @@ export const api = {
}),
resetDefault: () => request('/accounts/reset-default', { method: 'DELETE' }),
delete: (name: string) => request(`/accounts/${name}`, { method: 'DELETE' }),
+ updateContext: (name: string, data: UpdateAccountContext) =>
+ request(`/accounts/${encodeURIComponent(name)}/context`, {
+ method: 'PUT',
+ body: JSON.stringify(data),
+ }),
},
// Unified config API
config: {
diff --git a/ui/src/pages/accounts.tsx b/ui/src/pages/accounts.tsx
index bbed9c89..9a47b1df 100644
--- a/ui/src/pages/accounts.tsx
+++ b/ui/src/pages/accounts.tsx
@@ -11,7 +11,7 @@ import { Button } from '@/components/ui/button';
import { useAccounts } from '@/hooks/use-accounts';
export function AccountsPage() {
- const { data, isLoading, refetch } = useAccounts();
+ const { data, isLoading } = useAccounts();
const [createDialogOpen, setCreateDialogOpen] = useState(false);
return (
@@ -20,7 +20,7 @@ export function AccountsPage() {
Accounts
- Manage multi-account Claude sessions (profiles.json)
+ Manage multi-account Claude sessions and shared context groups