You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Runner's premise is that you stop scattering agent work across terminal windows — but there's no way to run a quick git status, ls, or pnpm test without leaving the app or burning a chat tab on it. Today the options are bouncing out to Ghostty or ⌘T-ing a chat, and neither fits a ten-second command.
A VS Code-style bottom panel: a drawer that toggles open over the bottom of the content area, holds one or more plain shell PTYs, and persists across route changes so a long-running pnpm dev keeps going while you move between chats and missions.
No spec doc for now — filing to capture the idea. Write one if this grows past a single drawer.
Scope sketch
Toggleable bottom drawer with a keyboard shortcut (VS Code uses ⌃``; ⌘Jis also free — seesrc/lib/keymap.ts`), resizable by dragging its top edge, height persisted.
Holds plain shell sessions — the user's $SHELL, cwd defaulting to the active project's bound directory, falling back to home.
Survives route changes. This is the load-bearing requirement: the drawer must live above the router like the sidebar does, not inside the chat surface.
Multiple shell tabs within the drawer would be nice; one is enough for v1.
Not an agent surface. No runner config, no crew slots, no mission participation, no event-log involvement.
Implementation notes
Most of the session plumbing already exists:
"shell" is already the fallback runtime name for sessions with no agent runtime — runtime_for() returns it (src-tauri/src/commands/session.rs:39, asserted at :1426), and it appears throughout test fixtures (commands/runner.rs:634, repo/runner.rs:221, commands/slot.rs:525).
Non-catalog runtimes already degrade correctly: resume_plan falls through to ResumePlan::fresh() (src-tauri/src/router/runtime.rs:660), model_effort_args/permission_mode_args/first_turn_argv all return empty, and runtime_clears_on_resize is false — a shell keeps its ring on resize, which is the right behavior.
So the backend gap is a spawn entry point for "plain $SHELL, no agent adapter", not new session machinery.
Open questions:
Where the drawer mounts. It must sit outside <Outlet /> in src/components/AppShell.tsx:101 to survive navigation. PersistentSurfaces solves an adjacent problem (keeping the last chat + mission mounted) and its visibility:hidden-not-display:none lesson from impl 0032 applies directly — a hidden drawer must stay measurable or its PTY geometry goes stale.
Whether shell sessions become rows. Persisting them means they show up in the sidebar and archive lists, which is probably wrong for a scratch shell. Ephemeral (drawer-local, dies with the app) is likely the better v1 — but that forfeits the auto-resume-on-launch behavior from feat: auto-resume running chats and missions on app launch #320.
Whether "shell" gets a real RUNTIME_DEFINITIONS entry. It would make the drawer reuse the normal spawn path and show up in Settings → Agents — but it would also appear in the chat runtime picker and crew slot dropdowns, which isn't wanted. Probably stays out of the catalog with a dedicated spawn command instead.
Relevant code
src/components/AppShell.tsx:101 — the flex shell where a bottom drawer would mount.
src/components/PersistentSurfaces.tsx — precedent for keeping a surface mounted across routes.
src/components/RunnerTerminal.tsx — the terminal component the drawer would host.
src/lib/keymap.ts — shortcut registry.
src-tauri/src/commands/session.rs — session_start_runtime is the closest existing spawn entry point.
src-tauri/src/router/runtime.rs — the non-catalog fallthrough behavior described above.
Motivation
Runner's premise is that you stop scattering agent work across terminal windows — but there's no way to run a quick
git status,ls, orpnpm testwithout leaving the app or burning a chat tab on it. Today the options are bouncing out to Ghostty or⌘T-ing a chat, and neither fits a ten-second command.A VS Code-style bottom panel: a drawer that toggles open over the bottom of the content area, holds one or more plain shell PTYs, and persists across route changes so a long-running
pnpm devkeeps going while you move between chats and missions.No spec doc for now — filing to capture the idea. Write one if this grows past a single drawer.
Scope sketch
⌃``;⌘Jis also free — seesrc/lib/keymap.ts`), resizable by dragging its top edge, height persisted.$SHELL, cwd defaulting to the active project's bound directory, falling back to home.Implementation notes
Most of the session plumbing already exists:
"shell"is already the fallback runtime name for sessions with no agent runtime —runtime_for()returns it (src-tauri/src/commands/session.rs:39, asserted at:1426), and it appears throughout test fixtures (commands/runner.rs:634,repo/runner.rs:221,commands/slot.rs:525).resume_planfalls through toResumePlan::fresh()(src-tauri/src/router/runtime.rs:660),model_effort_args/permission_mode_args/first_turn_argvall return empty, andruntime_clears_on_resizeis false — a shell keeps its ring on resize, which is the right behavior.Open questions:
<Outlet />insrc/components/AppShell.tsx:101to survive navigation.PersistentSurfacessolves an adjacent problem (keeping the last chat + mission mounted) and itsvisibility:hidden-not-display:nonelesson from impl 0032 applies directly — a hidden drawer must stay measurable or its PTY geometry goes stale."shell"gets a realRUNTIME_DEFINITIONSentry. It would make the drawer reuse the normal spawn path and show up in Settings → Agents — but it would also appear in the chat runtime picker and crew slot dropdowns, which isn't wanted. Probably stays out of the catalog with a dedicated spawn command instead.Relevant code
src/components/AppShell.tsx:101— the flex shell where a bottom drawer would mount.src/components/PersistentSurfaces.tsx— precedent for keeping a surface mounted across routes.src/components/RunnerTerminal.tsx— the terminal component the drawer would host.src/lib/keymap.ts— shortcut registry.src-tauri/src/commands/session.rs—session_start_runtimeis the closest existing spawn entry point.src-tauri/src/router/runtime.rs— the non-catalog fallthrough behavior described above.