feat: background blocking tools

This commit is contained in:
Dax Raad 2026-07-01 12:17:30 -04:00
commit e2bca216a2
15 changed files with 392 additions and 66 deletions

View file

@ -435,6 +435,23 @@ export function Prompt(props: PromptProps) {
dialog.clear()
},
},
{
title: "Background blocking tools",
name: "session.background",
category: "Session",
hidden: true,
enabled: status() === "running",
run: () => {
if (auto()?.visible) return
if (!input.focused) return
if (!props.sessionID) return
void sdk.api.session.background({
sessionID: props.sessionID,
})
dialog.clear()
},
},
{
title: "Open editor",
category: "Session",
@ -590,6 +607,7 @@ export function Prompt(props: PromptProps) {
"prompt.stash.list",
"prompt.skills",
"session.interrupt",
"session.background",
"workspace.set",
"session.move",
]),

View file

@ -94,7 +94,7 @@ export const Definitions = {
session_share: keybind("none", "Share current session"),
session_unshare: keybind("none", "Unshare current session"),
session_interrupt: keybind("escape", "Interrupt current session"),
session_background: keybind("ctrl+b", "Background synchronous subagents"),
session_background: keybind("ctrl+b", "Background blocking session tools"),
session_compact: keybind("<leader>c", "Compact the session"),
session_toggle_timestamps: keybind("none", "Toggle message timestamps"),
session_toggle_generic_tool_output: keybind("none", "Toggle generic tool output"),

View file

@ -782,11 +782,14 @@ export function Session() {
},
},
{
title: "Background subagents",
title: "Background blocking tools",
value: "session.background",
category: "Session",
hidden: true,
run: () => unavailable("Backgrounding subagents"),
run: () => {
void sdk.api.session.background({ sessionID: route.sessionID })
dialog.clear()
},
},
{
title: "Toggle subagent picker",
@ -920,6 +923,7 @@ export function Session() {
/>
)}
</For>
<BackgroundToolHint messages={messages()} />
<Show when={session()?.revert?.messageID}>
<RevertMessage
count={
@ -1037,6 +1041,34 @@ function SessionRowView(props: { row: SessionRow; message: (messageID: string) =
)
}
function BackgroundToolHint(props: { messages: SessionMessage[] }) {
const { theme } = useTheme()
const shortcut = useCommandShortcut("session.background")
const visible = createMemo(() => {
const current = props.messages.findLast(
(message): message is SessionMessageAssistant => message.type === "assistant" && !message.time.completed,
)
return (
current?.content.some((part) => {
if (part.type !== "tool" || part.state.status !== "running") return false
const display = toolDisplay(part.name)
return display === "shell" || display === "subagent"
}) ?? false
)
})
return (
<Show when={visible() && shortcut()}>
{(value) => (
<box marginTop={1} paddingLeft={3} flexShrink={0}>
<text fg={theme.textMuted}>
Press <span style={{ fg: theme.text }}>{value()}</span> to move running work to the background
</text>
</box>
)}
</Show>
)
}
function SessionMessageView(props: { message: SessionMessage }) {
return (
<Switch>