diff --git a/packages/app/src/pages/session/composer/session-question-dock.tsx b/packages/app/src/pages/session/composer/session-question-dock.tsx index 35690030c913..68b6f621551b 100644 --- a/packages/app/src/pages/session/composer/session-question-dock.tsx +++ b/packages/app/src/pages/session/composer/session-question-dock.tsx @@ -4,6 +4,7 @@ import { useMutation } from "@tanstack/solid-query" import { Button } from "@opencode-ai/ui/button" import { DockPrompt } from "@opencode-ai/ui/dock-prompt" import { Icon } from "@opencode-ai/ui/icon" +import { Markdown } from "@opencode-ai/ui/markdown" import { showToast } from "@opencode-ai/ui/toast" import type { QuestionAnswer, QuestionRequest } from "@opencode-ai/sdk/v2" import { useLanguage } from "@/context/language" @@ -73,6 +74,7 @@ export const SessionQuestionDock: Component<{ request: QuestionRequest; onSubmit customOn: cached?.customOn ?? ([] as boolean[]), editing: false, focus: 0, + minimized: false, }) let root: HTMLDivElement | undefined @@ -159,7 +161,7 @@ export const SessionQuestionDock: Component<{ request: QuestionRequest; onSubmit focusFrame = requestAnimationFrame(() => { focusFrame = undefined const el = next === options().length ? customRef : optsRef[next] - el?.focus() + el?.focus({ preventScroll: true }) }) } @@ -425,9 +427,16 @@ export const SessionQuestionDock: Component<{ request: QuestionRequest; onSubmit kind="question" ref={(el) => (root = el)} onKeyDown={nav} + minimized={store.minimized} header={ <> -
{summary()}
+
setStore("minimized", !store.minimized)} + > + {summary()} +
{(_, i) => ( @@ -469,7 +478,7 @@ export const SessionQuestionDock: Component<{ request: QuestionRequest; onSubmit } > -
{question()?.question}
+
{language.t("ui.question.singleHint")}
}>
{language.t("ui.question.multiHint")}
diff --git a/packages/opencode/src/tool/plan.ts b/packages/opencode/src/tool/plan.ts index af206f66a59d..a9284db493cd 100644 --- a/packages/opencode/src/tool/plan.ts +++ b/packages/opencode/src/tool/plan.ts @@ -25,12 +25,21 @@ export const PlanExitTool = Tool.define( Effect.gen(function* () { const instance = yield* InstanceState.context const info = yield* session.get(ctx.sessionID) - const plan = path.relative(instance.worktree, Session.plan(info, instance)) + const abs = Session.plan(info, instance) + const plan = path.relative(instance.worktree, abs) + const content = yield* Effect.promise(() => Bun.file(abs).text().catch(() => "")) + if (!content.trim()) { + return { + title: "Plan is empty", + output: `The plan file at ${plan} is empty. Please write the plan first before calling plan_exit.`, + metadata: {}, + } + } const answers = yield* question.ask({ sessionID: ctx.sessionID, questions: [ { - question: `Plan at ${plan} is complete. Would you like to switch to the build agent and start implementing?`, + question: `Plan at ${plan} is complete. Would you like to switch to the build agent and start implementing?\n\n---\n\n${content}`, header: "Build Agent", custom: false, options: [ diff --git a/packages/ui/src/components/dock-prompt.tsx b/packages/ui/src/components/dock-prompt.tsx index 01f1848c84c6..37733497bb36 100644 --- a/packages/ui/src/components/dock-prompt.tsx +++ b/packages/ui/src/components/dock-prompt.tsx @@ -1,4 +1,4 @@ -import type { JSX } from "solid-js" +import { Show, type JSX } from "solid-js" import { DockShell, DockTray } from "./dock-surface" export function DockPrompt(props: { @@ -6,18 +6,23 @@ export function DockPrompt(props: { header: JSX.Element children: JSX.Element footer: JSX.Element + minimized?: boolean ref?: (el: HTMLDivElement) => void onKeyDown?: JSX.EventHandlerUnion }) { const slot = (name: string) => `${props.kind}-${name}` return ( -
+
{props.header}
-
{props.children}
+ +
{props.children}
+
- {props.footer} + + {props.footer} +
) } diff --git a/packages/ui/src/components/dock-surface.css b/packages/ui/src/components/dock-surface.css index fd3430446405..671c82115ec0 100644 --- a/packages/ui/src/components/dock-surface.css +++ b/packages/ui/src/components/dock-surface.css @@ -4,7 +4,7 @@ position: relative; z-index: 10; border-radius: 12px; - overflow: clip; + overflow: hidden; } [data-dock-surface="tray"] { diff --git a/packages/ui/src/components/message-part.css b/packages/ui/src/components/message-part.css index 0dd02d812940..6032c55daf08 100644 --- a/packages/ui/src/components/message-part.css +++ b/packages/ui/src/components/message-part.css @@ -843,6 +843,10 @@ padding: 8px 8px 0; } + &[data-minimized="true"] [data-slot="question-body"] { + padding-bottom: 8px; + } + [data-slot="question-header"] { display: flex; align-items: center; @@ -858,6 +862,8 @@ line-height: var(--line-height-large); color: var(--text-strong); min-width: 0; + flex: 1; + cursor: pointer; } [data-slot="question-progress"] { @@ -909,6 +915,8 @@ gap: 4px; flex: 1; min-height: 0; + overflow-y: auto; + max-height: calc(var(--question-prompt-max-height, 70dvh) - 140px); } [data-slot="question-text"] { @@ -935,15 +943,6 @@ gap: 6px; margin-top: 12px; padding: 1px 1px 8px; - flex: 1; - min-height: 0; - overflow-y: auto; - scrollbar-width: none; - -ms-overflow-style: none; - - &::-webkit-scrollbar { - display: none; - } } [data-slot="question-option"] {