mirror of
https://github.com/anomalyco/opencode.git
synced 2026-05-21 03:15:11 +00:00
fix(tui): simplify thinking toggle styling (#28487)
This commit is contained in:
@@ -4,6 +4,14 @@
|
||||
- Local `main` ref may not exist; use `dev` or `origin/dev` for diffs.
|
||||
- Prefer automation: execute requested actions without confirmation unless blocked by missing info or safety/irreversibility.
|
||||
|
||||
## Commits and PR Titles
|
||||
|
||||
Use conventional commit-style messages and PR titles: `type(scope): summary`.
|
||||
|
||||
Valid types are `feat`, `fix`, `docs`, `chore`, `refactor`, and `test`. Scopes are optional; use the affected package or area when helpful, e.g. `core`, `opencode`, `tui`, `app`, `desktop`, `sdk`, or `plugin`.
|
||||
|
||||
Examples: `fix(tui): simplify thinking toggle styling`, `docs: update contributing guide`, `chore(sdk): regenerate types`.
|
||||
|
||||
## Style Guide
|
||||
|
||||
### General Principles
|
||||
|
||||
@@ -411,12 +411,9 @@ function AssistantReasoning(props: {
|
||||
<Switch>
|
||||
<Match when={!inMinimal() || expanded()}>
|
||||
<box
|
||||
paddingLeft={2}
|
||||
paddingLeft={3}
|
||||
marginTop={1}
|
||||
flexDirection="column"
|
||||
border={["left"]}
|
||||
customBorderChars={SplitBorder.customBorderChars}
|
||||
borderColor={theme.backgroundElement}
|
||||
flexShrink={0}
|
||||
onMouseUp={toggle}
|
||||
>
|
||||
@@ -425,17 +422,20 @@ function AssistantReasoning(props: {
|
||||
drawUnstyledText={false}
|
||||
streaming={true}
|
||||
syntaxStyle={props.subtleSyntax}
|
||||
content={(inMinimal() ? "▼ " : "") + "_Thinking:_ " + content()}
|
||||
content={(inMinimal() ? "- " : "") + "_Thinking:_ " + content()}
|
||||
conceal={true}
|
||||
fg={theme.textMuted}
|
||||
/>
|
||||
</box>
|
||||
</Match>
|
||||
<Match when={isDone()}>
|
||||
<box paddingLeft={3} marginTop={1} flexShrink={0} onMouseUp={toggle}>
|
||||
<text fg={theme.textMuted} wrapMode="none">
|
||||
{title() ? "▶ Thought: " + title() : "▶ Thought"}
|
||||
</text>
|
||||
<box
|
||||
paddingLeft={3}
|
||||
marginTop={1}
|
||||
flexShrink={0}
|
||||
onMouseUp={toggle}
|
||||
>
|
||||
<CollapsedReasoningText title={title()} />
|
||||
</box>
|
||||
</Match>
|
||||
<Match when={true}>
|
||||
@@ -448,6 +448,16 @@ function AssistantReasoning(props: {
|
||||
)
|
||||
}
|
||||
|
||||
function CollapsedReasoningText(props: { title: string | null }) {
|
||||
const { theme } = useTheme()
|
||||
|
||||
return (
|
||||
<text fg={theme.warning} wrapMode="none">
|
||||
<span style={{ fg: theme.warning, italic: true }}>{props.title ? "+ Thought · " + props.title : "+ Thought"}</span>
|
||||
</text>
|
||||
)
|
||||
}
|
||||
|
||||
function AssistantTool(props: { part: SessionMessageAssistantTool; sessionID: string }) {
|
||||
const input = createMemo(() => toolInputRecord(props.part.state.input))
|
||||
const toolprops = {
|
||||
|
||||
@@ -1533,12 +1533,9 @@ function ReasoningPart(props: { last: boolean; part: ReasoningPart; message: Ass
|
||||
{/* Full markdown block: `show` mode, or `hide` after the user opens it. */}
|
||||
<box
|
||||
id={"text-" + props.part.id}
|
||||
paddingLeft={2}
|
||||
paddingLeft={3}
|
||||
marginTop={1}
|
||||
flexDirection="column"
|
||||
border={["left"]}
|
||||
customBorderChars={SplitBorder.customBorderChars}
|
||||
borderColor={theme.backgroundElement}
|
||||
onMouseUp={toggle}
|
||||
>
|
||||
<code
|
||||
@@ -1546,26 +1543,24 @@ function ReasoningPart(props: { last: boolean; part: ReasoningPart; message: Ass
|
||||
drawUnstyledText={false}
|
||||
streaming={true}
|
||||
syntaxStyle={subtleSyntax()}
|
||||
content={(inMinimal() ? "▼ " : "") + (isDone() ? "_Thought:_ " : "_Thinking:_ ") + content()}
|
||||
content={(inMinimal() ? "- " : "") + (isDone() ? "_Thought:_ " : "_Thinking:_ ") + content()}
|
||||
conceal={ctx.conceal()}
|
||||
fg={theme.textMuted}
|
||||
/>
|
||||
</box>
|
||||
</Match>
|
||||
<Match when={isDone()}>
|
||||
{/* Settled: ▶ at the start as the click-to-expand cue. */}
|
||||
<box id={"text-" + props.part.id} paddingLeft={3} marginTop={1} flexShrink={0} onMouseUp={toggle}>
|
||||
<text fg={theme.textMuted} wrapMode="none">
|
||||
{"▶ " +
|
||||
(title()
|
||||
? "Thought: " + title() + " · " + Locale.duration(duration())
|
||||
: "Thought for " + Locale.duration(duration()))}
|
||||
</text>
|
||||
<box
|
||||
id={"text-" + props.part.id}
|
||||
paddingLeft={3}
|
||||
marginTop={1}
|
||||
flexShrink={0}
|
||||
onMouseUp={toggle}
|
||||
>
|
||||
<CollapsedReasoningText title={title()} duration={duration()} />
|
||||
</box>
|
||||
</Match>
|
||||
<Match when={true}>
|
||||
{/* Streaming: leading animated spinner, no disclosure arrow yet — it
|
||||
snaps in once reasoning settles, signalling "done, click to expand". */}
|
||||
<box id={"text-" + props.part.id} paddingLeft={3} marginTop={1} flexShrink={0} onMouseUp={toggle}>
|
||||
<Spinner color={theme.textMuted}>{title() ? "Thinking: " + title() : "Thinking"}</Spinner>
|
||||
</box>
|
||||
@@ -1575,6 +1570,19 @@ function ReasoningPart(props: { last: boolean; part: ReasoningPart; message: Ass
|
||||
)
|
||||
}
|
||||
|
||||
function CollapsedReasoningText(props: { title: string | null; duration: number }) {
|
||||
const { theme } = useTheme()
|
||||
const duration = () => Locale.duration(props.duration)
|
||||
|
||||
return (
|
||||
<text fg={theme.warning} wrapMode="none">
|
||||
<span style={{ fg: theme.warning, italic: true }}>
|
||||
{props.title ? "+ Thought · " + props.title + " · " + duration() : "+ Thought · " + duration()}
|
||||
</span>
|
||||
</text>
|
||||
)
|
||||
}
|
||||
|
||||
function TextPart(props: { last: boolean; part: TextPart; message: AssistantMessage }) {
|
||||
const ctx = use()
|
||||
const { theme, syntax } = useTheme()
|
||||
|
||||
Reference in New Issue
Block a user