Skip to content
Merged
6 changes: 3 additions & 3 deletions packages/app-bundle/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@
"packages/app/src/pages/new-session.tsx": "e69db43dfd9f29a3b8920bf63654f40772bfb0ab6d24029c7903a754c94e8571",
"packages/app/src/pages/overlay-content-hash.test.ts": "aa208098213522dcde42434408afe9c8641fad663f44a58c316922dbd0da2f5c",
"packages/app/src/pages/research-surfaces-absence.test.ts": "9944a8ec5492500eb82548d03b24ea7fb8ccc9c2ae5de14a4d18ddb309378746",
"packages/app/src/pages/session.tsx": "699f8644414fe44aab319c0338d2d3bdb552e1f5bc4d35f8229372b659694b3b",
"packages/app/src/pages/session.tsx": "1d71fdafbd3333af6766514ab44d22c11cc855ea82cdcfaf9ea2e0e5330a9736",
"packages/app/src/utils/amicode-bridge.ts": "3ec87c24c0384d312f7eb644807d9217a53b1b4b97f7fffadab1cc1595603f3b",
"packages/app/src/utils/amicode-bug-report.test.ts": "b1bbf49230ff3aa6d1a43ffa9165ba5a84ca4ee18a6d49f52ee5cd887c3e6444",
"packages/app/src/utils/amicode-bug-report.ts": "d55d9cecfe17719c0d4a0ca498345c7eff6fca1de6b645e4bc3fecb40f2f4645",
Expand Down Expand Up @@ -900,7 +900,7 @@
"packages/app/src/pages/session/session-panel-width.test.ts": "9482afba7fbce254cbbd21ef885e9e9620b981616681635376f466478f611155",
"packages/app/src/pages/session/session-panel-width.ts": "02ee3a02ed78db2eac47c2528055cf78aef95f389641e929ddc56c17471dcbe2",
"packages/app/src/pages/session/session-side-panel-structure.test.ts": "b2d1d007d9200d0ac4a0889e45c2dbe57a324a10cb26ae9ab8f420d3c890402b",
"packages/app/src/pages/session/session-side-panel.tsx": "43cbf60797b5b382e1cc6e69015f242d684ab92eb68f45a5dcef9cf56422d59a",
"packages/app/src/pages/session/session-side-panel.tsx": "d6c0cd6cdc2a586ce342b1ef91d68f4560d7c348891e5a83bc9665b671b892e9",
"packages/app/src/pages/session/terminal-panel-v2.tsx": "68dad9307f1d2abf3ff9248e451bd08005acf01ddc46b30a6d01b58f4a90dce0",
"packages/app/src/pages/session/use-amicode-commands.test.ts": "65671d054c404edd2b799b0f6591a9c055e6ecb454a674fa0bd9a7fa6f68e111",
"packages/app/src/pages/session/use-amicode-commands.tsx": "88bfdad9ae6dfd920b8e6a14ffebd2cf9e52b8f67bb9284cb358ad940643ca67",
Expand Down Expand Up @@ -1102,7 +1102,7 @@
"packages/ui/src/v2/components/text-shimmer-v2.tsx"
],
"exceptions": [],
"extracted_at": "2026-11-06T18:48:23.336Z",
"extracted_at": "2026-11-07T23:24:13.583Z",
"per_package": {
"packages/app": {
"A": 312,
Expand Down
67 changes: 57 additions & 10 deletions packages/app-bundle/overlay/packages/app/src/pages/session.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,37 @@ export default function Page() {
const workColumnWidth = createMemo(() =>
clampWorkColumnWidth({ width: layout.panelColumn.width(), available: sessionPanelAvailable() }),
)

// #1434: Wide mode — a fullscreen toggle for the Work Column that overrides
// the normal 60% cap. The resize handle stays bounded; only the toggle goes
// full-width. Declared before sessionPanelWidth so it can gate the chat width.
const [wideMode, setWideMode] = createSignal(false)
const [preWideColumnWidth, setPreWideColumnWidth] = createSignal<number | undefined>(undefined)

function toggleWide() {
if (wideMode()) {
setWideMode(false)
const restore = preWideColumnWidth()
if (restore) layout.panelColumn.resize(restore)
} else {
setPreWideColumnWidth(layout.panelColumn.width())
setWideMode(true)
}
}

// Cmd+Shift+M toggles wide mode
createEffect(() => {
if (!newSessionDesign()) return
function onKeyDown(e: KeyboardEvent) {
if ((e.metaKey || e.ctrlKey) && e.shiftKey && e.key.toLowerCase() === "m") {
e.preventDefault()
toggleWide()
}
}
window.addEventListener("keydown", onKeyDown)
onCleanup(() => window.removeEventListener("keydown", onKeyDown))
})

const sessionPanelWidth = createMemo(() => {
if (chatTakesRemainder()) return undefined
if (!desktopSidePanelOpen()) return "100%"
Expand Down Expand Up @@ -2820,25 +2851,38 @@ export default function Page() {
<SessionRouteFrame>
<SessionHeader />
<ContextWarningBanner />
<div
<div
ref={panelRow}
class="flex-1 min-h-0 flex flex-col md:flex-row"
classList={{
"gap-1.5 px-1.5 py-2": settings.general.newLayoutDesigns(),
"gap-1.5 px-1.5 py-2": settings.general.newLayoutDesigns() && !wideMode(),
"py-2": settings.general.newLayoutDesigns() && wideMode(),
}}
>
<Show when={!isDesktop() && !!params.id && !settings.general.newLayoutDesigns()}>{mobileTabs()}</Show>

<div
classList={{
"@container relative shrink-0 flex flex-col min-h-0 h-full transition-[width]": true,
"@container relative shrink-0 flex flex-col min-h-0 h-full transition-[width,opacity]": true,
"flex-1 md:flex-none": !chatTakesRemainder(),
"flex-1": chatTakesRemainder(),
"flex-1": chatTakesRemainder() && !wideMode(),
"duration-[240ms] ease-[cubic-bezier(0.22,1,0.36,1)] will-change-[width] motion-reduce:transition-none":
!size.active() && !ui.reviewSnap && !desktopInlineTerminalOnlyOpen(),
}}
style={{
width: sessionPanelWidth(),
// #1434: in wide mode, collapse Chat completely out of flow.
// Use position:absolute + visibility:hidden (not display:none)
// to preserve scroll geometry and avoid the #1510 cascade.
...(newSessionDesign() && wideMode() ? {
position: "absolute" as const,
visibility: "hidden" as const,
width: "0px",
height: "0px",
overflow: "hidden",
"pointer-events": "none",
} : {
width: sessionPanelWidth(),
}),
}}
>
{settings.general.newLayoutDesigns() ? (
Expand Down Expand Up @@ -2897,15 +2941,16 @@ export default function Page() {
<div
classList={{
"min-w-0 h-full flex flex-col relative": true,
"flex-1": !isDesktop(),
"flex-none": isDesktop(),
"flex-1": !isDesktop() || wideMode(),
"flex-none": isDesktop() && !wideMode(),
}}
style={{ width: isDesktop() ? `${workColumnWidth()}px` : undefined }}
style={{ width: isDesktop() && !wideMode() ? `${workColumnWidth()}px` : undefined }}
>
{/* amicode#105: the work column's own resize handle (its left
edge), sizing layout.panelColumn within the policy bounds —
the chat flexes around it, never below it. */}
<Show when={isDesktop()}>
the chat flexes around it, never below it. Hidden in wide
mode since the column fills the row. */}
<Show when={isDesktop() && !wideMode()}>
<div onPointerDown={() => size.start()}>
<ResizeHandle
direction="horizontal"
Expand Down Expand Up @@ -2942,6 +2987,8 @@ export default function Page() {
size={size}
stacked={desktopV2PanelLayout().stacked}
touchedFiles={touchedFiles}
isWide={wideMode}
onToggleWide={toggleWide}
/>
</Suspense>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,9 @@ export function SessionSidePanel(props: {
size: Sizing
stacked?: boolean
touchedFiles?: () => Array<{ file: string; status: string }>
/** #1434: Wide mode toggle */
isWide?: () => boolean
onToggleWide?: () => void
}) {
const layout = useLayout()
const settings = useSettings()
Expand Down Expand Up @@ -922,7 +925,24 @@ export function SessionSidePanel(props: {
</For>
</SortableProvider>
</Tabs.List>
<div class="shrink-0 flex items-center justify-center pl-2 pr-1">
<div class="shrink-0 flex items-center gap-1 pl-2 pr-1">
{/* #1434: Wide mode toggle pill */}
<Show when={props.onToggleWide}>
<button
class="flex items-center gap-1 px-2 py-0.5 rounded-full text-[11px] font-medium transition-colors"
classList={{
"bg-surface-accent/15 text-text-accent hover:bg-surface-accent/25": props.isWide?.() ?? false,
"bg-transparent text-text-dimmed hover:bg-background-interactive-hover hover:text-text-base": !(props.isWide?.() ?? false),
}}
title={props.isWide?.()
? `Exit Wide (${navigator.platform.includes("Mac") ? "⌘" : "Ctrl"}⇧M)`
: `Wide (${navigator.platform.includes("Mac") ? "⌘" : "Ctrl"}⇧M)`
}
onClick={() => props.onToggleWide?.()}
>
{props.isWide?.() ? "Exit Wide" : "Wide"}
</button>
</Show>
<PanelMenu items={panelMenuItems()} onSelect={handlePanelMenuSelect} />
</div>
</div>
Expand Down Expand Up @@ -1297,7 +1317,24 @@ export function SessionSidePanel(props: {
</For>
</DndKitProvider>
</Tabs.List>
<div class="shrink-0 flex items-center justify-center pl-2 pr-1">
<div class="shrink-0 flex items-center gap-1 pl-2 pr-1">
{/* #1434: Wide mode toggle pill (v2 path) */}
<Show when={props.onToggleWide}>
<button
class="flex items-center gap-1 px-2 py-0.5 rounded-full text-[11px] font-medium transition-colors"
classList={{
"bg-surface-accent/15 text-text-accent hover:bg-surface-accent/25": props.isWide?.() ?? false,
"bg-transparent text-text-dimmed hover:bg-background-interactive-hover hover:text-text-base": !(props.isWide?.() ?? false),
}}
title={props.isWide?.()
? `Exit Wide (${navigator.platform.includes("Mac") ? "⌘" : "Ctrl"}⇧M)`
: `Wide (${navigator.platform.includes("Mac") ? "⌘" : "Ctrl"}⇧M)`
}
onClick={() => props.onToggleWide?.()}
>
{props.isWide?.() ? "Exit Wide" : "Wide"}
</button>
</Show>
<PanelMenu items={panelMenuItems()} onSelect={handlePanelMenuSelect} v2 />
</div>
<div
Expand Down
Loading