persist panel sizes for email and automation screens, fix session title from prompt prefix

- switch email and automation screens from WorkspaceLayout to WorkspaceView + useWorkspacesState
- add promptPrefix prop to WorkspaceView, thread into WorkspaceContext
- automation dynamically adds/removes chat panel while preserving persisted sizes
- use displayText for session title so prompt prefix doesn't leak into titles
- fix email context filter to match screens/email workspace key

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-27 00:23:21 +00:00
co-authored by Claude Opus 4.6
parent c443fe0fe2
commit 968d502eaa
8 changed files with 73 additions and 73 deletions
@@ -22,7 +22,7 @@ function formatModel(model: string): string {
export const ChatHeader = () => {
const { workspaceId } = useWorkspace();
const contextFilter = workspaceId === 'email'
const contextFilter = workspaceId === 'email' || workspaceId === 'screens/email'
? { context: 'email' as const }
: workspaceId?.startsWith('proj-layout-')
? { context: 'project' as const, contextId: workspaceId.replace('proj-layout-', '') }
@@ -48,7 +48,7 @@ export const ChatPanelWrapper = () => {
const hostRoot = root === '~' || root === 'officer.dev';
const sandboxed = !hostRoot;
const chatContext = workspaceId === 'email'
const chatContext = workspaceId === 'email' || workspaceId === 'screens/email'
? { context: 'email' as const }
: workspaceId?.startsWith('proj-layout-')
? { context: 'project' as const, contextId: workspaceId.replace('proj-layout-', '') }
@@ -17,6 +17,7 @@ type WorkspaceViewProps = {
root?: string;
initialFilePath?: string;
defaultFileSort?: DefaultFileSort;
promptPrefix?: string;
components?: PanelComponents;
ephemeral?: EphemeralPanels | null;
mobilePanelId?: string;
@@ -25,7 +26,7 @@ type WorkspaceViewProps = {
const noop = () => {};
export const WorkspaceView = ({ workspace, locked, cwd = '~', root, initialFilePath, defaultFileSort, components, ephemeral, mobilePanelId, onMobilePanelChange }: WorkspaceViewProps) => {
export const WorkspaceView = ({ workspace, locked, cwd = '~', root, initialFilePath, defaultFileSort, promptPrefix, components, ephemeral, mobilePanelId, onMobilePanelChange }: WorkspaceViewProps) => {
const { registry } = useAppRegistry();
const isMobile = useIsMobile();
@@ -147,6 +148,7 @@ export const WorkspaceView = ({ workspace, locked, cwd = '~', root, initialFileP
root,
initialFilePath,
defaultFileSort,
promptPrefix,
swapSourceId,
setSwapSourceId,
onSwap: handleSwap,
@@ -293,6 +293,7 @@ export function usePiChat(initialSessionId?: string, initialModel?: string | nul
send({
type: 'chat',
prompt: text,
...(displayText ? { displayText } : {}),
sessionId: sessionIdRef.current,
...(selectedModel ? { model: selectedModel } : {}),
...(cwdParam?.path ? { cwd: cwdParam.path } : {}),