refactor(tui): expose theme colors as properties (#37995)
This commit is contained in:
parent
8cb9361149
commit
c0ba62b972
46 changed files with 740 additions and 749 deletions
|
|
@ -113,8 +113,8 @@ export function Composer(props: ComposerProps) {
|
|||
<box
|
||||
{...SplitBorder}
|
||||
border={["left"]}
|
||||
borderColor={themeV2.border()}
|
||||
backgroundColor={themeV2.background()}
|
||||
borderColor={themeV2.border.default}
|
||||
backgroundColor={themeV2.background.default}
|
||||
paddingLeft={1}
|
||||
paddingRight={2}
|
||||
paddingTop={1}
|
||||
|
|
@ -125,7 +125,7 @@ export function Composer(props: ComposerProps) {
|
|||
<Show
|
||||
when={tabList().length > 1}
|
||||
fallback={
|
||||
<text fg={themeV2.text()} attributes={TextAttributes.BOLD}>
|
||||
<text fg={themeV2.text.default} attributes={TextAttributes.BOLD}>
|
||||
{tabList()[0]?.label ?? ""}
|
||||
</text>
|
||||
}
|
||||
|
|
@ -136,7 +136,7 @@ export function Composer(props: ComposerProps) {
|
|||
const isActive = createMemo(() => store.active === t.id)
|
||||
return (
|
||||
<text
|
||||
fg={isActive() ? themeV2.text() : themeV2.text.subdued()}
|
||||
fg={isActive() ? themeV2.text.default : themeV2.text.subdued}
|
||||
attributes={isActive() ? TextAttributes.BOLD : undefined}
|
||||
>
|
||||
{t.label}
|
||||
|
|
@ -146,7 +146,7 @@ export function Composer(props: ComposerProps) {
|
|||
</For>
|
||||
</box>
|
||||
</Show>
|
||||
<text fg={themeV2.text.subdued()} onMouseUp={close}>
|
||||
<text fg={themeV2.text.subdued} onMouseUp={close}>
|
||||
esc
|
||||
</text>
|
||||
</box>
|
||||
|
|
@ -156,19 +156,19 @@ export function Composer(props: ComposerProps) {
|
|||
<For each={footerHints()}>
|
||||
{(hint) => (
|
||||
<text>
|
||||
<span style={{ fg: themeV2.text() }}>
|
||||
<span style={{ fg: themeV2.text.default }}>
|
||||
<b>{hint.label}</b>{" "}
|
||||
</span>
|
||||
<span style={{ fg: themeV2.text.subdued() }}>{hint.shortcut}</span>
|
||||
<span style={{ fg: themeV2.text.subdued }}>{hint.shortcut}</span>
|
||||
</text>
|
||||
)}
|
||||
</For>
|
||||
<Show when={tabList().length > 1}>
|
||||
<text>
|
||||
<span style={{ fg: themeV2.text() }}>
|
||||
<span style={{ fg: themeV2.text.default }}>
|
||||
<b>tabs</b>{" "}
|
||||
</span>
|
||||
<span style={{ fg: themeV2.text.subdued() }}>←/→</span>
|
||||
<span style={{ fg: themeV2.text.subdued }}>←/→</span>
|
||||
</text>
|
||||
</Show>
|
||||
</box>
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ export function ShellTab(props: { sessionID: string }) {
|
|||
return (
|
||||
<Show when={composer.active("shell")}>
|
||||
<scrollbox scrollbarOptions={{ visible: false }} maxHeight={5} ref={(r: ScrollBoxRenderable) => (scroll = r)}>
|
||||
<Show when={entries().length > 0} fallback={<text fg={themeV2.text.subdued()}> No shell commands</text>}>
|
||||
<Show when={entries().length > 0} fallback={<text fg={themeV2.text.subdued}> No shell commands</text>}>
|
||||
<For each={entries()}>
|
||||
{(shell, index) => {
|
||||
const active = createMemo(() => index() === store.selected)
|
||||
|
|
@ -107,11 +107,13 @@ export function ShellTab(props: { sessionID: string }) {
|
|||
flexDirection="row"
|
||||
paddingLeft={1}
|
||||
paddingRight={1}
|
||||
backgroundColor={themeV2.background.action({ focused: active() })}
|
||||
backgroundColor={
|
||||
active() ? themeV2.background.action.primary.focused : themeV2.background.action.primary.default
|
||||
}
|
||||
onMouseOver={() => setStore("selected", index())}
|
||||
>
|
||||
<text
|
||||
fg={themeV2.text.action({ focused: active() })}
|
||||
fg={active() ? themeV2.text.action.primary.focused : themeV2.text.action.primary.default}
|
||||
attributes={active() ? TextAttributes.BOLD : undefined}
|
||||
wrapMode="none"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ export function SubagentsTab(props: { sessionID: string }) {
|
|||
return (
|
||||
<Show when={composer.active("subagents")}>
|
||||
<scrollbox scrollbarOptions={{ visible: false }} maxHeight={5} ref={(r: ScrollBoxRenderable) => (scroll = r)}>
|
||||
<Show when={entries().length > 0} fallback={<text fg={themeV2.text.subdued()}> No subagents</text>}>
|
||||
<Show when={entries().length > 0} fallback={<text fg={themeV2.text.subdued}> No subagents</text>}>
|
||||
<For each={entries()}>
|
||||
{(entry, index) => {
|
||||
const active = createMemo(() => index() === selected())
|
||||
|
|
@ -218,7 +218,13 @@ export function SubagentsTab(props: { sessionID: string }) {
|
|||
flexDirection="row"
|
||||
paddingLeft={1}
|
||||
paddingRight={1}
|
||||
backgroundColor={themeV2.background.action({ focused: active(), selected: entry.current })}
|
||||
backgroundColor={
|
||||
active()
|
||||
? themeV2.background.action.primary.focused
|
||||
: entry.current
|
||||
? themeV2.background.action.primary.selected
|
||||
: themeV2.background.action.primary.default
|
||||
}
|
||||
onMouseOver={() => setStore("selected", index())}
|
||||
onMouseUp={() => {
|
||||
setStore("selected", index())
|
||||
|
|
@ -227,7 +233,13 @@ export function SubagentsTab(props: { sessionID: string }) {
|
|||
>
|
||||
<box flexGrow={1} minWidth={0} flexDirection="row">
|
||||
<text
|
||||
fg={themeV2.text.action({ focused: active(), selected: entry.current })}
|
||||
fg={
|
||||
active()
|
||||
? themeV2.text.action.primary.focused
|
||||
: entry.current
|
||||
? themeV2.text.action.primary.selected
|
||||
: themeV2.text.action.primary.default
|
||||
}
|
||||
attributes={active() ? TextAttributes.BOLD : undefined}
|
||||
wrapMode="none"
|
||||
>
|
||||
|
|
@ -235,14 +247,7 @@ export function SubagentsTab(props: { sessionID: string }) {
|
|||
</text>
|
||||
</box>
|
||||
<Show when={status()}>
|
||||
<text
|
||||
fg={
|
||||
active()
|
||||
? themeV2.text.action({ focused: active(), selected: entry.current })
|
||||
: themeV2.text.subdued()
|
||||
}
|
||||
wrapMode="none"
|
||||
>
|
||||
<text fg={active() ? themeV2.text.action.primary.focused : themeV2.text.subdued} wrapMode="none">
|
||||
{status()}
|
||||
</text>
|
||||
</Show>
|
||||
|
|
|
|||
|
|
@ -13,9 +13,7 @@ export function Footer() {
|
|||
const mcp = createMemo(
|
||||
() => (data.location.mcp.server.list() ?? []).filter((x) => x.status.status === "connected").length,
|
||||
)
|
||||
const mcpError = createMemo(() =>
|
||||
(data.location.mcp.server.list() ?? []).some((x) => x.status.status === "failed"),
|
||||
)
|
||||
const mcpError = createMemo(() => (data.location.mcp.server.list() ?? []).some((x) => x.status.status === "failed"))
|
||||
const permissions = createMemo(() => {
|
||||
if (route.data.type !== "session") return []
|
||||
return data.session.permission.list(route.data.sessionID) ?? []
|
||||
|
|
@ -54,35 +52,35 @@ export function Footer() {
|
|||
|
||||
return (
|
||||
<box flexDirection="row" justifyContent="space-between" gap={1} flexShrink={0}>
|
||||
<text fg={themeV2.text.subdued()}>{directory()}</text>
|
||||
<text fg={themeV2.text.subdued}>{directory()}</text>
|
||||
<box gap={2} flexDirection="row" flexShrink={0}>
|
||||
<Switch>
|
||||
<Match when={store.welcome}>
|
||||
<text fg={themeV2.text()}>
|
||||
Get started <span style={{ fg: themeV2.text.subdued() }}>/connect</span>
|
||||
<text fg={themeV2.text.default}>
|
||||
Get started <span style={{ fg: themeV2.text.subdued }}>/connect</span>
|
||||
</text>
|
||||
</Match>
|
||||
<Match when={connected()}>
|
||||
<Show when={permissions().length > 0}>
|
||||
<text fg={themeV2.text.feedback.warning()}>
|
||||
<span style={{ fg: themeV2.text.feedback.warning() }}>△</span> {permissions().length} Permission
|
||||
<text fg={themeV2.text.feedback.warning.default}>
|
||||
<span style={{ fg: themeV2.text.feedback.warning.default }}>△</span> {permissions().length} Permission
|
||||
{permissions().length > 1 ? "s" : ""}
|
||||
</text>
|
||||
</Show>
|
||||
<Show when={mcp()}>
|
||||
<text fg={themeV2.text()}>
|
||||
<text fg={themeV2.text.default}>
|
||||
<Switch>
|
||||
<Match when={mcpError()}>
|
||||
<span style={{ fg: themeV2.text.feedback.error() }}>⊙ </span>
|
||||
<span style={{ fg: themeV2.text.feedback.error.default }}>⊙ </span>
|
||||
</Match>
|
||||
<Match when={true}>
|
||||
<span style={{ fg: themeV2.text.feedback.success() }}>⊙ </span>
|
||||
<span style={{ fg: themeV2.text.feedback.success.default }}>⊙ </span>
|
||||
</Match>
|
||||
</Switch>
|
||||
{mcp()} MCP
|
||||
</text>
|
||||
</Show>
|
||||
<text fg={themeV2.text.subdued()}>/status</text>
|
||||
<text fg={themeV2.text.subdued}>/status</text>
|
||||
</Match>
|
||||
</Switch>
|
||||
</box>
|
||||
|
|
|
|||
|
|
@ -624,27 +624,27 @@ export function FormPrompt(props: { form: FormWithLocation }) {
|
|||
|
||||
return (
|
||||
<box
|
||||
backgroundColor={themeV2.background()}
|
||||
backgroundColor={themeV2.background.default}
|
||||
border={["left"]}
|
||||
borderColor={themeV2.hue.interactive(themeMode() === "light" ? 800 : 200)}
|
||||
borderColor={themeV2.hue.interactive[themeMode() === "light" ? 800 : 200]}
|
||||
customBorderChars={SplitBorder.customBorderChars}
|
||||
>
|
||||
<box gap={1} paddingLeft={1} paddingRight={3} paddingTop={1} paddingBottom={1}>
|
||||
<box paddingLeft={1}>
|
||||
<text fg={themeV2.text.subdued()}>{props.form.title}</text>
|
||||
<text fg={themeV2.text.subdued}>{props.form.title}</text>
|
||||
</box>
|
||||
<Show when={message()}>
|
||||
<box paddingLeft={1}>
|
||||
<text fg={themeV2.text()}>{message()}</text>
|
||||
<text fg={themeV2.text.default}>{message()}</text>
|
||||
</box>
|
||||
</Show>
|
||||
<Show when={!single() && !tabbed()}>
|
||||
<box flexDirection="row" gap={1} paddingLeft={1}>
|
||||
<text fg={themeV2.text.subdued()}>
|
||||
<text fg={themeV2.text.subdued}>
|
||||
{confirm() ? "Review" : `Field ${Math.min(store.tab, fields().length - 1) + 1} of ${fields().length}`}
|
||||
</text>
|
||||
<Show when={fields().length > 0}>
|
||||
<text fg={themeV2.text.subdued()}>
|
||||
<text fg={themeV2.text.subdued}>
|
||||
· {answered()}/{fields().length} completed
|
||||
</text>
|
||||
</Show>
|
||||
|
|
@ -661,10 +661,10 @@ export function FormPrompt(props: { form: FormWithLocation }) {
|
|||
paddingRight={2}
|
||||
backgroundColor={
|
||||
isTab()
|
||||
? themeV2.background.formfield("selected")
|
||||
? themeV2.background.formfield.selected
|
||||
: tabHover() === index()
|
||||
? themeV2.background.formfield("focused")
|
||||
: themeV2.background()
|
||||
? themeV2.background.formfield.focused
|
||||
: themeV2.background.default
|
||||
}
|
||||
onMouseOver={() => setTabHover(index())}
|
||||
onMouseOut={() => setTabHover(null)}
|
||||
|
|
@ -676,12 +676,12 @@ export function FormPrompt(props: { form: FormWithLocation }) {
|
|||
<text
|
||||
fg={
|
||||
isTab()
|
||||
? themeV2.text.formfield("selected")
|
||||
? themeV2.text.formfield.selected
|
||||
: tabHover() === index()
|
||||
? themeV2.text.formfield("focused")
|
||||
? themeV2.text.formfield.focused
|
||||
: isAnswered()
|
||||
? themeV2.text()
|
||||
: themeV2.text.subdued()
|
||||
? themeV2.text.default
|
||||
: themeV2.text.subdued
|
||||
}
|
||||
>
|
||||
{truncate(formLabel(item), 24)}
|
||||
|
|
@ -693,10 +693,10 @@ export function FormPrompt(props: { form: FormWithLocation }) {
|
|||
<box
|
||||
backgroundColor={
|
||||
confirm()
|
||||
? themeV2.background.formfield("selected")
|
||||
? themeV2.background.formfield.selected
|
||||
: tabHover() === "confirm"
|
||||
? themeV2.background.formfield("focused")
|
||||
: themeV2.background()
|
||||
? themeV2.background.formfield.focused
|
||||
: themeV2.background.default
|
||||
}
|
||||
onMouseOver={() => setTabHover("confirm")}
|
||||
onMouseOut={() => setTabHover(null)}
|
||||
|
|
@ -705,7 +705,7 @@ export function FormPrompt(props: { form: FormWithLocation }) {
|
|||
selectTabFromMouse()
|
||||
}}
|
||||
>
|
||||
<text fg={themeV2.text.formfield(confirm() ? "selected" : "default")}>Confirm</text>
|
||||
<text fg={confirm() ? themeV2.text.formfield.selected : themeV2.text.formfield.default}>Confirm</text>
|
||||
</box>
|
||||
</box>
|
||||
</Show>
|
||||
|
|
@ -714,13 +714,13 @@ export function FormPrompt(props: { form: FormWithLocation }) {
|
|||
{(external) => (
|
||||
<box paddingLeft={1} gap={1}>
|
||||
<Show when={external().title}>
|
||||
<text fg={themeV2.text()}>{external().title}</text>
|
||||
<text fg={themeV2.text.default}>{external().title}</text>
|
||||
</Show>
|
||||
<Show when={external().description}>
|
||||
<text fg={themeV2.text.subdued()}>{external().description}</text>
|
||||
<text fg={themeV2.text.subdued}>{external().description}</text>
|
||||
</Show>
|
||||
<text
|
||||
fg={themeV2.background.action()}
|
||||
fg={themeV2.background.action.primary.default}
|
||||
onMouseUp={() => {
|
||||
if (renderer.getSelection()?.getSelectedText()) return
|
||||
openExternal()
|
||||
|
|
@ -729,7 +729,9 @@ export function FormPrompt(props: { form: FormWithLocation }) {
|
|||
{external().url}
|
||||
</text>
|
||||
<text
|
||||
fg={store.answers[external().key] === true ? themeV2.text.feedback.success() : themeV2.text.subdued()}
|
||||
fg={
|
||||
store.answers[external().key] === true ? themeV2.text.feedback.success.default : themeV2.text.subdued
|
||||
}
|
||||
>
|
||||
{store.answers[external().key] === true
|
||||
? "✓ Acknowledged"
|
||||
|
|
@ -744,7 +746,7 @@ export function FormPrompt(props: { form: FormWithLocation }) {
|
|||
<Show when={!confirm() && answerField()}>
|
||||
<box paddingLeft={1} gap={1}>
|
||||
<box>
|
||||
<text fg={themeV2.text()}>
|
||||
<text fg={themeV2.text.default}>
|
||||
{answerField()!.description ?? formLabel(answerField()!)}
|
||||
{answerField()!.required ? " (required)" : ""}
|
||||
{multi() ? " (select all that apply)" : ""}
|
||||
|
|
@ -765,12 +767,12 @@ export function FormPrompt(props: { form: FormWithLocation }) {
|
|||
input() || formDisplayValue(answerField()!, store.answers[answerField()!.key], "(none)")
|
||||
}
|
||||
placeholder={placeholder()}
|
||||
placeholderColor={themeV2.text.subdued()}
|
||||
placeholderColor={themeV2.text.subdued}
|
||||
minHeight={1}
|
||||
maxHeight={6}
|
||||
textColor={themeV2.text()}
|
||||
focusedTextColor={themeV2.text()}
|
||||
cursorColor={themeV2.text()}
|
||||
textColor={themeV2.text.default}
|
||||
focusedTextColor={themeV2.text.default}
|
||||
cursorColor={themeV2.text.default}
|
||||
/>
|
||||
</box>
|
||||
</Show>
|
||||
|
|
@ -795,25 +797,39 @@ export function FormPrompt(props: { form: FormWithLocation }) {
|
|||
>
|
||||
<box flexDirection="row">
|
||||
<box
|
||||
backgroundColor={active() ? themeV2.background.formfield("focused") : themeV2.background()}
|
||||
backgroundColor={
|
||||
active() ? themeV2.background.formfield.focused : themeV2.background.default
|
||||
}
|
||||
paddingRight={1}
|
||||
>
|
||||
<text fg={themeV2.text.formfield(active() ? "focused" : "default")}>{`${i() + 1}.`}</text>
|
||||
<text
|
||||
fg={active() ? themeV2.text.formfield.focused : themeV2.text.formfield.default}
|
||||
>{`${i() + 1}.`}</text>
|
||||
</box>
|
||||
<box
|
||||
backgroundColor={active() ? themeV2.background.formfield("focused") : themeV2.background()}
|
||||
backgroundColor={
|
||||
active() ? themeV2.background.formfield.focused : themeV2.background.default
|
||||
}
|
||||
>
|
||||
<text fg={themeV2.text.formfield(active() ? "focused" : picked() ? "selected" : "default")}>
|
||||
<text
|
||||
fg={
|
||||
active()
|
||||
? themeV2.text.formfield.focused
|
||||
: picked()
|
||||
? themeV2.text.formfield.selected
|
||||
: themeV2.text.formfield.default
|
||||
}
|
||||
>
|
||||
{multi() ? `[${picked() ? "✓" : " "}] ${row.label}` : row.label}
|
||||
</text>
|
||||
</box>
|
||||
<Show when={!multi()}>
|
||||
<text fg={themeV2.text.formfield("selected")}>{picked() ? " ✓" : ""}</text>
|
||||
<text fg={themeV2.text.formfield.selected}>{picked() ? " ✓" : ""}</text>
|
||||
</Show>
|
||||
</box>
|
||||
<Show when={row.description}>
|
||||
<box paddingLeft={3}>
|
||||
<text fg={themeV2.text.subdued()}>{row.description}</text>
|
||||
<text fg={themeV2.text.subdued}>{row.description}</text>
|
||||
</box>
|
||||
</Show>
|
||||
</box>
|
||||
|
|
@ -831,28 +847,30 @@ export function FormPrompt(props: { form: FormWithLocation }) {
|
|||
>
|
||||
<box flexDirection="row">
|
||||
<box
|
||||
backgroundColor={other() ? themeV2.background.formfield("focused") : themeV2.background()}
|
||||
backgroundColor={other() ? themeV2.background.formfield.focused : themeV2.background.default}
|
||||
paddingRight={1}
|
||||
>
|
||||
<text fg={themeV2.text.formfield(other() ? "focused" : "default")}>
|
||||
<text fg={other() ? themeV2.text.formfield.focused : themeV2.text.formfield.default}>
|
||||
{`${rows().length + 1}.`}
|
||||
</text>
|
||||
</box>
|
||||
<box backgroundColor={other() ? themeV2.background.formfield("focused") : themeV2.background()}>
|
||||
<box
|
||||
backgroundColor={other() ? themeV2.background.formfield.focused : themeV2.background.default}
|
||||
>
|
||||
<text
|
||||
fg={
|
||||
other()
|
||||
? themeV2.text.formfield("focused")
|
||||
? themeV2.text.formfield.focused
|
||||
: customPicked()
|
||||
? themeV2.text.feedback.success()
|
||||
: themeV2.text()
|
||||
? themeV2.text.feedback.success.default
|
||||
: themeV2.text.default
|
||||
}
|
||||
>
|
||||
{multi() ? `[${customPicked() ? "✓" : " "}] Type your own answer` : "Type your own answer"}
|
||||
</text>
|
||||
</box>
|
||||
<Show when={!multi()}>
|
||||
<text fg={themeV2.text.feedback.success()}>{customPicked() ? " ✓" : ""}</text>
|
||||
<text fg={themeV2.text.feedback.success.default}>{customPicked() ? " ✓" : ""}</text>
|
||||
</Show>
|
||||
</box>
|
||||
<Show when={store.editing}>
|
||||
|
|
@ -868,18 +886,18 @@ export function FormPrompt(props: { form: FormWithLocation }) {
|
|||
}}
|
||||
initialValue={input()}
|
||||
placeholder="Type your own answer"
|
||||
placeholderColor={themeV2.text.subdued()}
|
||||
placeholderColor={themeV2.text.subdued}
|
||||
minHeight={1}
|
||||
maxHeight={6}
|
||||
textColor={themeV2.text()}
|
||||
focusedTextColor={themeV2.text()}
|
||||
cursorColor={themeV2.text()}
|
||||
textColor={themeV2.text.default}
|
||||
focusedTextColor={themeV2.text.default}
|
||||
cursorColor={themeV2.text.default}
|
||||
/>
|
||||
</box>
|
||||
</Show>
|
||||
<Show when={!store.editing && input()}>
|
||||
<box paddingLeft={3}>
|
||||
<text fg={themeV2.text.subdued()}>{input()}</text>
|
||||
<text fg={themeV2.text.subdued}>{input()}</text>
|
||||
</box>
|
||||
</Show>
|
||||
</box>
|
||||
|
|
@ -892,7 +910,7 @@ export function FormPrompt(props: { form: FormWithLocation }) {
|
|||
<Show when={confirm()}>
|
||||
<Show when={tabbed()}>
|
||||
<box paddingLeft={1}>
|
||||
<text fg={themeV2.text()}>Review</text>
|
||||
<text fg={themeV2.text.default}>Review</text>
|
||||
</box>
|
||||
</Show>
|
||||
<scrollbox
|
||||
|
|
@ -907,10 +925,12 @@ export function FormPrompt(props: { form: FormWithLocation }) {
|
|||
return (
|
||||
<box paddingLeft={1}>
|
||||
<text>
|
||||
<span style={{ fg: themeV2.text.subdued() }}>{truncate(formLabel(item), 40)}:</span>{" "}
|
||||
<span style={{ fg: themeV2.text.subdued }}>{truncate(formLabel(item), 40)}:</span>{" "}
|
||||
<span
|
||||
style={{
|
||||
fg: acknowledged() ? themeV2.text.feedback.success() : themeV2.text.feedback.error(),
|
||||
fg: acknowledged()
|
||||
? themeV2.text.feedback.success.default
|
||||
: themeV2.text.feedback.error.default,
|
||||
}}
|
||||
>
|
||||
{acknowledged() ? "Acknowledged" : "(acknowledgement required)"}
|
||||
|
|
@ -926,15 +946,15 @@ export function FormPrompt(props: { form: FormWithLocation }) {
|
|||
return (
|
||||
<box paddingLeft={1}>
|
||||
<text>
|
||||
<span style={{ fg: themeV2.text.subdued() }}>{truncate(formLabel(item), 40)}:</span>{" "}
|
||||
<span style={{ fg: themeV2.text.subdued }}>{truncate(formLabel(item), 40)}:</span>{" "}
|
||||
<span
|
||||
style={{
|
||||
fg:
|
||||
invalid() || missing()
|
||||
? themeV2.text.feedback.error()
|
||||
? themeV2.text.feedback.error.default
|
||||
: answered()
|
||||
? themeV2.text()
|
||||
: themeV2.text.subdued(),
|
||||
? themeV2.text.default
|
||||
: themeV2.text.subdued,
|
||||
}}
|
||||
>
|
||||
{invalid() ?? (answered() ? value() : missing() ? "(required)" : "(not answered)")}
|
||||
|
|
@ -958,41 +978,41 @@ export function FormPrompt(props: { form: FormWithLocation }) {
|
|||
>
|
||||
<box flexDirection="row" gap={2}>
|
||||
<Show when={!single()}>
|
||||
<text fg={themeV2.text()}>
|
||||
{"⇆"} <span style={{ fg: themeV2.text.subdued() }}>tab</span>
|
||||
<text fg={themeV2.text.default}>
|
||||
{"⇆"} <span style={{ fg: themeV2.text.subdued }}>tab</span>
|
||||
</text>
|
||||
</Show>
|
||||
<Show when={!confirm() && !textual() && !externalField()}>
|
||||
<text fg={themeV2.text()}>
|
||||
{"↑↓"} <span style={{ fg: themeV2.text.subdued() }}>select</span>
|
||||
<text fg={themeV2.text.default}>
|
||||
{"↑↓"} <span style={{ fg: themeV2.text.subdued }}>select</span>
|
||||
</text>
|
||||
</Show>
|
||||
<Show when={confirm() && fields().length > 0}>
|
||||
<text fg={themeV2.text()}>
|
||||
{"↑↓"} <span style={{ fg: themeV2.text.subdued() }}>scroll</span>
|
||||
<text fg={themeV2.text.default}>
|
||||
{"↑↓"} <span style={{ fg: themeV2.text.subdued }}>scroll</span>
|
||||
</text>
|
||||
</Show>
|
||||
<text
|
||||
fg={themeV2.text()}
|
||||
fg={themeV2.text.default}
|
||||
onMouseUp={() => {
|
||||
if (renderer.getSelection()?.getSelectedText()) return
|
||||
if (confirm()) submit()
|
||||
if (externalField()) acknowledgeExternal()
|
||||
}}
|
||||
>
|
||||
enter <span style={{ fg: themeV2.text.subdued() }}>{actionLabel()}</span>
|
||||
enter <span style={{ fg: themeV2.text.subdued }}>{actionLabel()}</span>
|
||||
</text>
|
||||
<Show when={externalField() && clipboard.write}>
|
||||
<text fg={themeV2.text()} onMouseUp={copyExternal}>
|
||||
c <span style={{ fg: themeV2.text.subdued() }}>copy</span>
|
||||
<text fg={themeV2.text.default} onMouseUp={copyExternal}>
|
||||
c <span style={{ fg: themeV2.text.subdued }}>copy</span>
|
||||
</text>
|
||||
</Show>
|
||||
<text fg={themeV2.text()} onMouseUp={cancel}>
|
||||
esc <span style={{ fg: themeV2.text.subdued() }}>dismiss</span>
|
||||
<text fg={themeV2.text.default} onMouseUp={cancel}>
|
||||
esc <span style={{ fg: themeV2.text.subdued }}>dismiss</span>
|
||||
</text>
|
||||
</box>
|
||||
<Show when={store.error}>
|
||||
<text fg={themeV2.text.feedback.error()}>{store.error}</text>
|
||||
<text fg={themeV2.text.feedback.error.default}>{store.error}</text>
|
||||
</Show>
|
||||
</box>
|
||||
</box>
|
||||
|
|
|
|||
|
|
@ -919,8 +919,8 @@ export function Session() {
|
|||
paddingLeft: 1,
|
||||
visible: showScrollbar(),
|
||||
trackOptions: {
|
||||
backgroundColor: themeV2.raise(themeV2.background.surface.offset()),
|
||||
foregroundColor: themeV2.border(),
|
||||
backgroundColor: themeV2.raise(themeV2.background.surface.offset),
|
||||
foregroundColor: themeV2.border.default,
|
||||
},
|
||||
}}
|
||||
stickyScroll={!navigationMessage()}
|
||||
|
|
@ -1098,8 +1098,8 @@ function BackgroundToolHint(props: { messages: SessionMessageInfo[] }) {
|
|||
<Show when={visible() && shortcut()}>
|
||||
{(value) => (
|
||||
<box marginTop={1} paddingLeft={3} flexShrink={0}>
|
||||
<text fg={themeV2.text.subdued()}>
|
||||
Press <span style={{ fg: themeV2.text() }}>{value()}</span> to move running work to the background
|
||||
<text fg={themeV2.text.subdued}>
|
||||
Press <span style={{ fg: themeV2.text.default }}>{value()}</span> to move running work to the background
|
||||
</text>
|
||||
</box>
|
||||
)}
|
||||
|
|
@ -1209,13 +1209,13 @@ function SessionReasoningGroupView(props: {
|
|||
icon={expanded() ? "-" : "+"}
|
||||
color={
|
||||
!props.completed
|
||||
? themeV2.text()
|
||||
? themeV2.text.default
|
||||
: hover() || expanded()
|
||||
? themeV2.text.feedback.warning()
|
||||
? themeV2.text.feedback.warning.default
|
||||
: RGBA.fromValues(
|
||||
themeV2.text.feedback.warning().r,
|
||||
themeV2.text.feedback.warning().g,
|
||||
themeV2.text.feedback.warning().b,
|
||||
themeV2.text.feedback.warning.default.r,
|
||||
themeV2.text.feedback.warning.default.g,
|
||||
themeV2.text.feedback.warning.default.b,
|
||||
0.6,
|
||||
)
|
||||
}
|
||||
|
|
@ -1258,7 +1258,7 @@ function SessionReasoningGroupView(props: {
|
|||
<box
|
||||
border={["left"]}
|
||||
customBorderChars={SplitBorder.customBorderChars}
|
||||
borderColor={themeV2.raise(themeV2.background.surface.offset())}
|
||||
borderColor={themeV2.raise(themeV2.background.surface.offset)}
|
||||
paddingLeft={1}
|
||||
>
|
||||
<code
|
||||
|
|
@ -1268,7 +1268,7 @@ function SessionReasoningGroupView(props: {
|
|||
syntaxStyle={syntax()}
|
||||
content={content()}
|
||||
conceal={ctx.markdownMode() === "rendered"}
|
||||
fg={themeV2.text.subdued()}
|
||||
fg={themeV2.text.subdued}
|
||||
/>
|
||||
</box>
|
||||
</box>
|
||||
|
|
@ -1326,7 +1326,7 @@ function SessionGroupView(props: {
|
|||
<Show when={grouped().length > 0}>
|
||||
<InlineToolRow
|
||||
icon={props.completed ? "→" : "✱"}
|
||||
color={hover() ? themeV2.text() : themeV2.text.subdued()}
|
||||
color={hover() ? themeV2.text.default : themeV2.text.subdued}
|
||||
complete={props.completed}
|
||||
pending={label()}
|
||||
spinner={!props.completed}
|
||||
|
|
@ -1372,25 +1372,25 @@ function AssistantFooter(props: { message: SessionMessageAssistant }) {
|
|||
paddingTop={1}
|
||||
paddingBottom={1}
|
||||
paddingLeft={2}
|
||||
backgroundColor={themeV2.background()}
|
||||
backgroundColor={themeV2.background.default}
|
||||
customBorderChars={SplitBorder.customBorderChars}
|
||||
borderColor={themeV2.text.feedback.error()}
|
||||
borderColor={themeV2.text.feedback.error.default}
|
||||
>
|
||||
<text fg={themeV2.text.subdued()}>{errorMessage(props.message.error)}</text>
|
||||
<text fg={themeV2.text.subdued}>{errorMessage(props.message.error)}</text>
|
||||
</box>
|
||||
</Show>
|
||||
<AssistantRetry retry={props.message.retry} />
|
||||
<box paddingLeft={3} marginTop={props.message.error && !interrupted() ? 1 : 0}>
|
||||
<text>
|
||||
<span style={{ fg: props.message.error ? themeV2.text.subdued() : local.agent.color(props.message.agent) }}>
|
||||
<span style={{ fg: props.message.error ? themeV2.text.subdued : local.agent.color(props.message.agent) }}>
|
||||
{Locale.titlecase(props.message.agent)}
|
||||
</span>
|
||||
<span style={{ fg: themeV2.text.subdued() }}> · {model()}</span>
|
||||
<span style={{ fg: themeV2.text.subdued }}> · {model()}</span>
|
||||
<Show when={duration()}>
|
||||
<span style={{ fg: themeV2.text.subdued() }}> · {Locale.duration(duration())}</span>
|
||||
<span style={{ fg: themeV2.text.subdued }}> · {Locale.duration(duration())}</span>
|
||||
</Show>
|
||||
<Show when={interrupted()}>
|
||||
<span style={{ fg: themeV2.text.subdued() }}> · interrupted</span>
|
||||
<span style={{ fg: themeV2.text.subdued }}> · interrupted</span>
|
||||
</Show>
|
||||
</text>
|
||||
</box>
|
||||
|
|
@ -1409,7 +1409,7 @@ function SessionSwitchMessageV2(props: { message: SessionMessageInfo }) {
|
|||
}
|
||||
return (
|
||||
<box paddingLeft={3}>
|
||||
<text fg={themeV2.text.subdued()}>{text()}</text>
|
||||
<text fg={themeV2.text.subdued}>{text()}</text>
|
||||
</box>
|
||||
)
|
||||
}
|
||||
|
|
@ -1436,15 +1436,15 @@ function SessionNoticeMessageV2(props: { message: SessionMessageInfo }) {
|
|||
const heading = () => `${state() === "completed" ? "↳" : "!"} ${actor()} ${status()}`
|
||||
const suffix = () => Locale.truncateWidth(` · ${description()}`, Math.max(0, ctx.width - 3 - stringWidth(heading())))
|
||||
const color = () => {
|
||||
if (state() === "error") return themeV2.text.feedback.error()
|
||||
if (state() === "cancelled") return themeV2.text.feedback.warning()
|
||||
return themeV2.text.feedback.info()
|
||||
if (state() === "error") return themeV2.text.feedback.error.default
|
||||
if (state() === "cancelled") return themeV2.text.feedback.warning.default
|
||||
return themeV2.text.feedback.info.default
|
||||
}
|
||||
return (
|
||||
<Show
|
||||
when={completion()}
|
||||
fallback={
|
||||
<InlineToolRow icon="◈" color={themeV2.text.subdued()} pending="Notice" complete={true}>
|
||||
<InlineToolRow icon="◈" color={themeV2.text.subdued} pending="Notice" complete={true}>
|
||||
{text()}
|
||||
</InlineToolRow>
|
||||
}
|
||||
|
|
@ -1452,7 +1452,7 @@ function SessionNoticeMessageV2(props: { message: SessionMessageInfo }) {
|
|||
<box marginLeft={3}>
|
||||
<text wrapMode="none">
|
||||
<span style={{ fg: color() }}>{heading()}</span>
|
||||
<span style={{ fg: themeV2.text.subdued() }}>{suffix()}</span>
|
||||
<span style={{ fg: themeV2.text.subdued }}>{suffix()}</span>
|
||||
</text>
|
||||
</box>
|
||||
</Show>
|
||||
|
|
@ -1462,7 +1462,7 @@ function SessionNoticeMessageV2(props: { message: SessionMessageInfo }) {
|
|||
function SessionSkillMessage(props: { message: Extract<SessionMessageInfo, { type: "skill" }> }) {
|
||||
const { themeV2 } = useTheme()
|
||||
return (
|
||||
<InlineToolRow icon="→" color={themeV2.text.subdued()} pending="Skill" complete={true}>
|
||||
<InlineToolRow icon="→" color={themeV2.text.subdued} pending="Skill" complete={true}>
|
||||
Skill {props.message.name}
|
||||
</InlineToolRow>
|
||||
)
|
||||
|
|
@ -1476,7 +1476,8 @@ function CompactionMessage(props: { message: Extract<SessionMessageInfo, { type:
|
|||
const text = () =>
|
||||
props.message.status === "failed" ? (cancelled() ? "" : props.message.error.message) : props.message.summary
|
||||
const content = createMemo(() => text().trim())
|
||||
const color = () => (status() === "failed" && !cancelled() ? themeV2.text.feedback.error() : themeV2.text.subdued())
|
||||
const color = () =>
|
||||
status() === "failed" && !cancelled() ? themeV2.text.feedback.error.default : themeV2.text.subdued
|
||||
return (
|
||||
<box>
|
||||
<box flexDirection="row" alignItems="center">
|
||||
|
|
@ -1508,8 +1509,8 @@ function CompactionMessage(props: { message: Extract<SessionMessageInfo, { type:
|
|||
content={content()}
|
||||
tableOptions={{ style: "grid" }}
|
||||
conceal={ctx.markdownMode() === "rendered"}
|
||||
fg={themeV2.markdown()}
|
||||
bg={themeV2.background()}
|
||||
fg={themeV2.markdown.text}
|
||||
bg={themeV2.background.default}
|
||||
/>
|
||||
</box>
|
||||
</Show>
|
||||
|
|
@ -1521,12 +1522,12 @@ function CompactionQueued() {
|
|||
const { themeV2 } = useTheme()
|
||||
return (
|
||||
<box flexDirection="row" alignItems="center">
|
||||
<box border={["top"]} borderColor={themeV2.border()} flexGrow={1} />
|
||||
<box border={["top"]} borderColor={themeV2.border.default} flexGrow={1} />
|
||||
<box flexDirection="row" gap={1} paddingLeft={1} paddingRight={1}>
|
||||
<text fg={themeV2.text.subdued()}>◇</text>
|
||||
<text fg={themeV2.text.subdued()}>Compaction queued</text>
|
||||
<text fg={themeV2.text.subdued}>◇</text>
|
||||
<text fg={themeV2.text.subdued}>Compaction queued</text>
|
||||
</box>
|
||||
<box border={["top"]} borderColor={themeV2.border()} flexGrow={1} />
|
||||
<box border={["top"]} borderColor={themeV2.border.default} flexGrow={1} />
|
||||
</box>
|
||||
)
|
||||
}
|
||||
|
|
@ -1572,15 +1573,15 @@ function RevertMessage(props: {
|
|||
marginTop={1}
|
||||
border={["left"]}
|
||||
customBorderChars={SplitBorder.customBorderChars}
|
||||
borderColor={themeV2.background()}
|
||||
borderColor={themeV2.background.default}
|
||||
>
|
||||
<box
|
||||
paddingTop={1}
|
||||
paddingBottom={1}
|
||||
paddingLeft={2}
|
||||
backgroundColor={hover() ? themeV2.raise(themeV2.background()) : themeV2.background()}
|
||||
backgroundColor={hover() ? themeV2.raise(themeV2.background.default) : themeV2.background.default}
|
||||
>
|
||||
<text fg={themeV2.text.subdued()}>
|
||||
<text fg={themeV2.text.subdued}>
|
||||
{props.count} message{props.count === 1 ? "" : "s"} reverted
|
||||
</text>
|
||||
<Show when={props.files.length > 0}>
|
||||
|
|
@ -1588,7 +1589,7 @@ function RevertMessage(props: {
|
|||
<For each={props.files}>
|
||||
{(file) => (
|
||||
<box flexDirection="row" gap={1} flexShrink={0}>
|
||||
<text fg={themeV2.text.subdued()}>{statusLabel(file.status)}</text>
|
||||
<text fg={themeV2.text.subdued}>{statusLabel(file.status)}</text>
|
||||
<FilePath
|
||||
value={file.file}
|
||||
maxWidth={Math.max(
|
||||
|
|
@ -1598,21 +1599,21 @@ function RevertMessage(props: {
|
|||
(file.additions > 0 ? stringWidth(`+${file.additions}`) + 1 : 0) -
|
||||
(file.deletions > 0 ? stringWidth(`-${file.deletions}`) + 1 : 0),
|
||||
)}
|
||||
fg={themeV2.text()}
|
||||
fg={themeV2.text.default}
|
||||
/>
|
||||
<Show when={file.additions > 0}>
|
||||
<text fg={themeV2.diff.text.added()}>+{file.additions}</text>
|
||||
<text fg={themeV2.diff.text.added}>+{file.additions}</text>
|
||||
</Show>
|
||||
<Show when={file.deletions > 0}>
|
||||
<text fg={themeV2.diff.text.removed()}>-{file.deletions}</text>
|
||||
<text fg={themeV2.diff.text.removed}>-{file.deletions}</text>
|
||||
</Show>
|
||||
</box>
|
||||
)}
|
||||
</For>
|
||||
</box>
|
||||
</Show>
|
||||
<text fg={themeV2.text.subdued()}>
|
||||
<span style={{ fg: themeV2.text() }}>{redoKey()}</span> or /redo to restore
|
||||
<text fg={themeV2.text.subdued}>
|
||||
<span style={{ fg: themeV2.text.default }}>{redoKey()}</span> or /redo to restore
|
||||
</text>
|
||||
</box>
|
||||
</box>
|
||||
|
|
@ -1630,13 +1631,13 @@ function ShellMessage(props: { message: Extract<SessionMessageInfo, { type: "she
|
|||
paddingBottom={1}
|
||||
paddingLeft={2}
|
||||
gap={1}
|
||||
backgroundColor={themeV2.background()}
|
||||
backgroundColor={themeV2.background.default}
|
||||
customBorderChars={SplitBorder.customBorderChars}
|
||||
borderColor={themeV2.background()}
|
||||
borderColor={themeV2.background.default}
|
||||
>
|
||||
<text fg={themeV2.text()}>$ {props.message.command}</text>
|
||||
<text fg={themeV2.text.default}>$ {props.message.command}</text>
|
||||
<Show when={output()}>
|
||||
<text fg={themeV2.text.subdued()}>{output()}</text>
|
||||
<text fg={themeV2.text.subdued}>{output()}</text>
|
||||
</Show>
|
||||
</box>
|
||||
)
|
||||
|
|
@ -1661,7 +1662,7 @@ function UserMessage(props: { message: SessionMessageUser }) {
|
|||
<Show when={props.message.text.trim() || files().length}>
|
||||
<box
|
||||
border={["left"]}
|
||||
borderColor={queued() ? themeV2.border() : color()}
|
||||
borderColor={queued() ? themeV2.border.default : color()}
|
||||
customBorderChars={SplitBorder.customBorderChars}
|
||||
>
|
||||
<box
|
||||
|
|
@ -1684,27 +1685,27 @@ function UserMessage(props: { message: SessionMessageUser }) {
|
|||
paddingTop={1}
|
||||
paddingBottom={1}
|
||||
paddingLeft={2}
|
||||
backgroundColor={hover() ? themeV2.raise(themeV2.background()) : themeV2.background()}
|
||||
backgroundColor={hover() ? themeV2.raise(themeV2.background.default) : themeV2.background.default}
|
||||
flexShrink={0}
|
||||
>
|
||||
<text fg={themeV2.text()}>{props.message.text}</text>
|
||||
<text fg={themeV2.text.default}>{props.message.text}</text>
|
||||
<Show when={files().length}>
|
||||
<box flexDirection="row" paddingTop={1} gap={1} flexWrap="wrap">
|
||||
<For each={files()}>
|
||||
{(file) => {
|
||||
const label = file.mime === "application/x-directory" ? "dir" : "file"
|
||||
return (
|
||||
<text fg={themeV2.text()}>
|
||||
<text fg={themeV2.text.default}>
|
||||
<span
|
||||
style={{
|
||||
bg: themeV2.hue.accent(mode() === "light" ? 700 : 200),
|
||||
fg: themeV2.background(),
|
||||
bg: themeV2.hue.accent[mode() === "light" ? 700 : 200],
|
||||
fg: themeV2.background.default,
|
||||
bold: true,
|
||||
}}
|
||||
>
|
||||
{` ${label} `}
|
||||
</span>
|
||||
<span style={{ bg: themeV2.raise(themeV2.background()), fg: themeV2.text.subdued() }}>
|
||||
<span style={{ bg: themeV2.raise(themeV2.background.default), fg: themeV2.text.subdued }}>
|
||||
{" "}
|
||||
{file.name ?? (file.source.type === "uri" ? file.source.uri : "attachment")}{" "}
|
||||
</span>
|
||||
|
|
@ -1809,11 +1810,11 @@ function AssistantMessage(props: { message: SessionMessageAssistant; last: boole
|
|||
paddingTop={1}
|
||||
paddingBottom={1}
|
||||
paddingLeft={2}
|
||||
backgroundColor={themeV2.background()}
|
||||
backgroundColor={themeV2.background.default}
|
||||
customBorderChars={SplitBorder.customBorderChars}
|
||||
borderColor={themeV2.text.feedback.error()}
|
||||
borderColor={themeV2.text.feedback.error.default}
|
||||
>
|
||||
<text fg={themeV2.text.subdued()}>{errorMessage(props.message.error)}</text>
|
||||
<text fg={themeV2.text.subdued}>{errorMessage(props.message.error)}</text>
|
||||
</box>
|
||||
</Show>
|
||||
<AssistantRetry retry={props.message.retry} />
|
||||
|
|
@ -1821,14 +1822,12 @@ function AssistantMessage(props: { message: SessionMessageAssistant; last: boole
|
|||
<Match when={props.last || final() || props.message.error}>
|
||||
<box paddingLeft={3}>
|
||||
<text>
|
||||
<span
|
||||
style={{ fg: props.message.error ? themeV2.text.subdued() : local.agent.color(props.message.agent) }}
|
||||
>
|
||||
<span style={{ fg: props.message.error ? themeV2.text.subdued : local.agent.color(props.message.agent) }}>
|
||||
{Locale.titlecase(props.message.agent)}
|
||||
</span>
|
||||
<span style={{ fg: themeV2.text.subdued() }}> · {model()}</span>
|
||||
<span style={{ fg: themeV2.text.subdued }}> · {model()}</span>
|
||||
<Show when={duration()}>
|
||||
<span style={{ fg: themeV2.text.subdued() }}> · {Locale.duration(duration())}</span>
|
||||
<span style={{ fg: themeV2.text.subdued }}> · {Locale.duration(duration())}</span>
|
||||
</Show>
|
||||
</text>
|
||||
</box>
|
||||
|
|
@ -1844,7 +1843,7 @@ function AssistantRetry(props: { retry: SessionMessageAssistant["retry"] }) {
|
|||
<Show when={props.retry}>
|
||||
{(retry) => (
|
||||
<box paddingLeft={3} marginTop={1}>
|
||||
<text fg={themeV2.text.subdued()}>
|
||||
<text fg={themeV2.text.subdued}>
|
||||
Retry attempt {retry().attempt} scheduled: {retry().error.message} [{retry().error.type}]
|
||||
</text>
|
||||
</box>
|
||||
|
|
@ -1867,7 +1866,7 @@ function ExplorationSummary(props: { parts: SessionMessageAssistantTool[]; activ
|
|||
<box flexDirection="column">
|
||||
<InlineToolRow
|
||||
icon="✱"
|
||||
color={themeV2.text.subdued()}
|
||||
color={themeV2.text.subdued}
|
||||
complete={!props.active}
|
||||
pending="Exploring"
|
||||
spinner={props.active}
|
||||
|
|
@ -1877,7 +1876,7 @@ function ExplorationSummary(props: { parts: SessionMessageAssistantTool[]; activ
|
|||
<For each={props.parts}>
|
||||
{(part, index) => (
|
||||
<box paddingLeft={5}>
|
||||
<text fg={part.state.status === "error" ? themeV2.text.feedback.error() : themeV2.text.subdued()}>
|
||||
<text fg={part.state.status === "error" ? themeV2.text.feedback.error.default : themeV2.text.subdued}>
|
||||
{index() === props.parts.length - 1 ? "└" : "├"} {label(part)}
|
||||
</text>
|
||||
</box>
|
||||
|
|
@ -1922,7 +1921,7 @@ function ReasoningPart(props: {
|
|||
<box
|
||||
border={!inMinimal() || expanded() ? ["left"] : undefined}
|
||||
customBorderChars={SplitBorder.customBorderChars}
|
||||
borderColor={themeV2.raise(themeV2.background())}
|
||||
borderColor={themeV2.raise(themeV2.background.default)}
|
||||
paddingLeft={!inMinimal() || expanded() ? 1 : 0}
|
||||
>
|
||||
<box onMouseUp={toggle}>
|
||||
|
|
@ -1940,7 +1939,7 @@ function ReasoningPart(props: {
|
|||
<box
|
||||
border={["left"]}
|
||||
customBorderChars={SplitBorder.customBorderChars}
|
||||
borderColor={themeV2.raise(themeV2.background())}
|
||||
borderColor={themeV2.raise(themeV2.background.default)}
|
||||
paddingLeft={inMinimal() ? 3 : 1}
|
||||
>
|
||||
<code
|
||||
|
|
@ -1950,7 +1949,7 @@ function ReasoningPart(props: {
|
|||
syntaxStyle={syntax()}
|
||||
content={content()}
|
||||
conceal={ctx.markdownMode() === "rendered"}
|
||||
fg={themeV2.text.subdued()}
|
||||
fg={themeV2.text.subdued}
|
||||
/>
|
||||
</box>
|
||||
</box>
|
||||
|
|
@ -1976,12 +1975,12 @@ function ReasoningHeader(props: {
|
|||
const fg = () =>
|
||||
props.open
|
||||
? RGBA.fromValues(
|
||||
themeV2.text.feedback.warning().r,
|
||||
themeV2.text.feedback.warning().g,
|
||||
themeV2.text.feedback.warning().b,
|
||||
themeV2.text.feedback.warning.default.r,
|
||||
themeV2.text.feedback.warning.default.g,
|
||||
themeV2.text.feedback.warning.default.b,
|
||||
0.6,
|
||||
)
|
||||
: themeV2.text.feedback.warning()
|
||||
: themeV2.text.feedback.warning.default
|
||||
|
||||
return (
|
||||
<Switch>
|
||||
|
|
@ -2027,8 +2026,8 @@ function TextPart(props: { last: boolean; part: SessionMessageAssistantText }) {
|
|||
content={props.part.text.trim()}
|
||||
tableOptions={{ style: "grid" }}
|
||||
conceal={ctx.markdownMode() === "rendered"}
|
||||
fg={themeV2.markdown()}
|
||||
bg={themeV2.background()}
|
||||
fg={themeV2.markdown.text}
|
||||
bg={themeV2.background.default}
|
||||
/>
|
||||
</box>
|
||||
</Show>
|
||||
|
|
@ -2135,7 +2134,7 @@ function GenericTool(props: ToolProps) {
|
|||
<Show when={Object.keys(props.input).length > 0}>
|
||||
<box gap={1}>
|
||||
<text>
|
||||
<span style={{ bg: themeV2.raise(themeV2.background()), fg: themeV2.text.subdued() }}> Input </span>
|
||||
<span style={{ bg: themeV2.raise(themeV2.background.default), fg: themeV2.text.subdued }}> Input </span>
|
||||
</text>
|
||||
<box paddingLeft={1}>
|
||||
<code
|
||||
|
|
@ -2144,7 +2143,7 @@ function GenericTool(props: ToolProps) {
|
|||
syntaxStyle={syntax()}
|
||||
conceal={false}
|
||||
drawUnstyledText={false}
|
||||
fg={themeV2.text()}
|
||||
fg={themeV2.text.default}
|
||||
/>
|
||||
</box>
|
||||
</box>
|
||||
|
|
@ -2153,10 +2152,13 @@ function GenericTool(props: ToolProps) {
|
|||
{(value) => (
|
||||
<box gap={1}>
|
||||
<text>
|
||||
<span style={{ bg: themeV2.raise(themeV2.background()), fg: themeV2.text.subdued() }}> Output </span>
|
||||
<span style={{ bg: themeV2.raise(themeV2.background.default), fg: themeV2.text.subdued }}>
|
||||
{" "}
|
||||
Output{" "}
|
||||
</span>
|
||||
</text>
|
||||
<box paddingLeft={1}>
|
||||
<text fg={themeV2.text()} wrapMode="word">
|
||||
<text fg={themeV2.text.default} wrapMode="word">
|
||||
{value()}
|
||||
</text>
|
||||
</box>
|
||||
|
|
@ -2208,10 +2210,10 @@ function InlineTool(props: {
|
|||
const clickable = createMemo(() => Boolean(props.onClick || failed()))
|
||||
const fg = createMemo(() => {
|
||||
if (props.color) return props.color
|
||||
if (permission()) return themeV2.text.feedback.warning()
|
||||
if (failed()) return themeV2.text.feedback.error()
|
||||
if (hover() && props.onClick) return themeV2.text()
|
||||
return themeV2.text.subdued()
|
||||
if (permission()) return themeV2.text.feedback.warning.default
|
||||
if (failed()) return themeV2.text.feedback.error.default
|
||||
if (hover() && props.onClick) return themeV2.text.default
|
||||
return themeV2.text.subdued
|
||||
})
|
||||
|
||||
return (
|
||||
|
|
@ -2219,7 +2221,7 @@ function InlineTool(props: {
|
|||
icon={props.icon}
|
||||
iconColor={props.iconColor}
|
||||
color={fg()}
|
||||
errorColor={themeV2.text.feedback.error()}
|
||||
errorColor={themeV2.text.feedback.error.default}
|
||||
failed={failed()}
|
||||
denied={Boolean(denied())}
|
||||
error={error()}
|
||||
|
|
@ -2343,7 +2345,7 @@ function InlineToolLabel(props: { color?: RGBA; denied?: boolean; status: JSX.El
|
|||
function StatusBadge(props: { children: string }) {
|
||||
const { themeV2 } = useTheme()
|
||||
return (
|
||||
<text flexShrink={0} bg={themeV2.raise(themeV2.background())} fg={themeV2.text.subdued()}>
|
||||
<text flexShrink={0} bg={themeV2.raise(themeV2.background.default)} fg={themeV2.text.subdued}>
|
||||
{" "}
|
||||
{props.children}{" "}
|
||||
</text>
|
||||
|
|
@ -2376,9 +2378,9 @@ function BlockTool(props: {
|
|||
paddingBottom={1}
|
||||
paddingLeft={2}
|
||||
gap={1}
|
||||
backgroundColor={hover() ? themeV2.raise(themeV2.background()) : themeV2.background()}
|
||||
backgroundColor={hover() ? themeV2.raise(themeV2.background.default) : themeV2.background.default}
|
||||
customBorderChars={SplitBorder.customBorderChars}
|
||||
borderColor={themeV2.background()}
|
||||
borderColor={themeV2.background.default}
|
||||
onMouseOver={() => props.onClick && setHover(true)}
|
||||
onMouseOut={() => setHover(false)}
|
||||
onMouseUp={() => {
|
||||
|
|
@ -2394,10 +2396,12 @@ function BlockTool(props: {
|
|||
<Show
|
||||
when={props.spinner}
|
||||
fallback={
|
||||
<text fg={permission() ? themeV2.text.feedback.warning() : themeV2.text.subdued()}>{title()}</text>
|
||||
<text fg={permission() ? themeV2.text.feedback.warning.default : themeV2.text.subdued}>
|
||||
{title()}
|
||||
</text>
|
||||
}
|
||||
>
|
||||
<Spinner color={permission() ? themeV2.text.feedback.warning() : themeV2.text.subdued()}>
|
||||
<Spinner color={permission() ? themeV2.text.feedback.warning.default : themeV2.text.subdued}>
|
||||
{title().replace(/^# /, "")}
|
||||
</Spinner>
|
||||
</Show>
|
||||
|
|
@ -2410,26 +2414,26 @@ function BlockTool(props: {
|
|||
<Show
|
||||
when={props.spinner}
|
||||
fallback={
|
||||
<text flexShrink={0} fg={permission() ? themeV2.text.feedback.warning() : themeV2.text.subdued()}>
|
||||
<text flexShrink={0} fg={permission() ? themeV2.text.feedback.warning.default : themeV2.text.subdued}>
|
||||
{path().label}
|
||||
</text>
|
||||
}
|
||||
>
|
||||
<Spinner color={permission() ? themeV2.text.feedback.warning() : themeV2.text.subdued()}>
|
||||
<Spinner color={permission() ? themeV2.text.feedback.warning.default : themeV2.text.subdued}>
|
||||
{path().label.replace(/^# /, "")}
|
||||
</Spinner>
|
||||
</Show>
|
||||
<FilePath
|
||||
value={path().value}
|
||||
maxWidth={Math.max(2, ctx.width - 4 - stringWidth(path().label) - (props.spinner ? 2 : 0))}
|
||||
fg={permission() ? themeV2.text.feedback.warning() : themeV2.text.subdued()}
|
||||
fg={permission() ? themeV2.text.feedback.warning.default : themeV2.text.subdued}
|
||||
/>
|
||||
</box>
|
||||
)}
|
||||
</Show>
|
||||
{props.children}
|
||||
<Show when={error()}>
|
||||
<text fg={themeV2.text.feedback.error()}>{error()}</text>
|
||||
<text fg={themeV2.text.feedback.error.default}>{error()}</text>
|
||||
</Show>
|
||||
</box>
|
||||
)
|
||||
|
|
@ -2444,7 +2448,7 @@ function Shell(props: ToolProps) {
|
|||
const request = data.session.permission.list(ctx.sessionID)?.[0]
|
||||
return request?.source?.type === "tool" && request.source.callID === props.part.id
|
||||
})
|
||||
const color = createMemo(() => (permission() ? themeV2.text.feedback.warning() : themeV2.text()))
|
||||
const color = createMemo(() => (permission() ? themeV2.text.feedback.warning.default : themeV2.text.default))
|
||||
const shellID = createMemo(() => stringValue(props.metadata.shellID))
|
||||
const backgroundRunning = createMemo(() => {
|
||||
const id = shellID()
|
||||
|
|
@ -2506,7 +2510,7 @@ function Shell(props: ToolProps) {
|
|||
isRunning() || props.part.state.status === "streaming" ? (
|
||||
<Spinner color={color()}>Writing command...</Spinner>
|
||||
) : (
|
||||
<text fg={themeV2.text.subdued()}>Writing command...</text>
|
||||
<text fg={themeV2.text.subdued}>Writing command...</text>
|
||||
)
|
||||
}
|
||||
>
|
||||
|
|
@ -2514,14 +2518,14 @@ function Shell(props: ToolProps) {
|
|||
when={isRunning()}
|
||||
fallback={
|
||||
<text>
|
||||
<span style={{ fg: themeV2.text() }}>{limited().slice(0, input().length)}</span>
|
||||
<span style={{ fg: themeV2.text.subdued() }}>{limited().slice(input().length)}</span>
|
||||
<span style={{ fg: themeV2.text.default }}>{limited().slice(0, input().length)}</span>
|
||||
<span style={{ fg: themeV2.text.subdued }}>{limited().slice(input().length)}</span>
|
||||
</text>
|
||||
}
|
||||
>
|
||||
<Spinner color={color()}>
|
||||
<span style={{ fg: themeV2.text() }}>{limited().slice(0, input().length)}</span>
|
||||
<span style={{ fg: themeV2.text.subdued() }}>{limited().slice(input().length)}</span>
|
||||
<span style={{ fg: themeV2.text.default }}>{limited().slice(0, input().length)}</span>
|
||||
<span style={{ fg: themeV2.text.subdued }}>{limited().slice(input().length)}</span>
|
||||
</Spinner>
|
||||
</Show>
|
||||
</Show>
|
||||
|
|
@ -2547,10 +2551,10 @@ function Write(props: ToolProps) {
|
|||
path={{ label: "# Wrote", value: pathFormatter.format(stringValue(props.input.path)) }}
|
||||
part={props.part}
|
||||
>
|
||||
<line_number fg={themeV2.text.subdued()} minWidth={3} paddingRight={1}>
|
||||
<line_number fg={themeV2.text.subdued} minWidth={3} paddingRight={1}>
|
||||
<code
|
||||
conceal={false}
|
||||
fg={themeV2.text()}
|
||||
fg={themeV2.text.default}
|
||||
filetype={filetype(stringValue(props.input.path))}
|
||||
syntaxStyle={syntax()}
|
||||
content={code()}
|
||||
|
|
@ -2605,7 +2609,7 @@ function Read(props: ToolProps) {
|
|||
<For each={loaded()}>
|
||||
{(filepath) => (
|
||||
<box paddingLeft={3}>
|
||||
<text paddingLeft={3} fg={themeV2.text.subdued()}>
|
||||
<text paddingLeft={3} fg={themeV2.text.subdued}>
|
||||
↳ Loaded {pathFormatter.format(filepath)}
|
||||
</text>
|
||||
</box>
|
||||
|
|
@ -2724,7 +2728,7 @@ function Execute(props: ToolProps) {
|
|||
<>
|
||||
<InlineTool
|
||||
icon={hasRuntimeError() ? "✗" : props.part.state.status === "completed" ? "✓" : "│"}
|
||||
color={hasRuntimeError() ? themeV2.text.feedback.error() : undefined}
|
||||
color={hasRuntimeError() ? themeV2.text.feedback.error.default : undefined}
|
||||
spinner={isLoading()}
|
||||
pending="execute"
|
||||
complete={true}
|
||||
|
|
@ -2736,7 +2740,7 @@ function Execute(props: ToolProps) {
|
|||
<box paddingLeft={3}>
|
||||
<For each={outputPreview().split("\n")}>
|
||||
{(line, index) => (
|
||||
<text paddingLeft={3} fg={themeV2.text.feedback.error()}>
|
||||
<text paddingLeft={3} fg={themeV2.text.feedback.error.default}>
|
||||
{index() === 0 ? "↳ " : " "}
|
||||
{line}
|
||||
</text>
|
||||
|
|
@ -2778,16 +2782,16 @@ function Edit(props: ToolProps) {
|
|||
showLineNumbers={true}
|
||||
width="100%"
|
||||
wrapMode={ctx.diffWrapMode()}
|
||||
fg={themeV2.text()}
|
||||
addedBg={themeV2.diff.background.added()}
|
||||
removedBg={themeV2.diff.background.removed()}
|
||||
contextBg={themeV2.diff.background.context()}
|
||||
addedSignColor={themeV2.diff.highlight.added()}
|
||||
removedSignColor={themeV2.diff.highlight.removed()}
|
||||
lineNumberFg={themeV2.diff.lineNumber.text()}
|
||||
lineNumberBg={themeV2.diff.background.context()}
|
||||
addedLineNumberBg={themeV2.diff.lineNumber.background.added()}
|
||||
removedLineNumberBg={themeV2.diff.lineNumber.background.removed()}
|
||||
fg={themeV2.text.default}
|
||||
addedBg={themeV2.diff.background.added}
|
||||
removedBg={themeV2.diff.background.removed}
|
||||
contextBg={themeV2.diff.background.context}
|
||||
addedSignColor={themeV2.diff.highlight.added}
|
||||
removedSignColor={themeV2.diff.highlight.removed}
|
||||
lineNumberFg={themeV2.diff.lineNumber.text}
|
||||
lineNumberBg={themeV2.diff.background.context}
|
||||
addedLineNumberBg={themeV2.diff.lineNumber.background.added}
|
||||
removedLineNumberBg={themeV2.diff.lineNumber.background.removed}
|
||||
/>
|
||||
</box>
|
||||
<Diagnostics diagnostics={props.metadata.diagnostics} filePath={stringValue(props.input.path) ?? ""} />
|
||||
|
|
@ -2852,7 +2856,7 @@ function ApplyPatch(props: ToolProps) {
|
|||
<Show
|
||||
when={file.type !== "delete"}
|
||||
fallback={
|
||||
<text fg={themeV2.diff.text.removed()}>
|
||||
<text fg={themeV2.diff.text.removed}>
|
||||
-{file.deletions} line{file.deletions !== 1 ? "s" : ""}
|
||||
</text>
|
||||
}
|
||||
|
|
@ -2866,16 +2870,16 @@ function ApplyPatch(props: ToolProps) {
|
|||
showLineNumbers={true}
|
||||
width="100%"
|
||||
wrapMode={ctx.diffWrapMode()}
|
||||
fg={themeV2.text()}
|
||||
addedBg={themeV2.diff.background.added()}
|
||||
removedBg={themeV2.diff.background.removed()}
|
||||
contextBg={themeV2.diff.background.context()}
|
||||
addedSignColor={themeV2.diff.highlight.added()}
|
||||
removedSignColor={themeV2.diff.highlight.removed()}
|
||||
lineNumberFg={themeV2.diff.lineNumber.text()}
|
||||
lineNumberBg={themeV2.diff.background.context()}
|
||||
addedLineNumberBg={themeV2.diff.lineNumber.background.added()}
|
||||
removedLineNumberBg={themeV2.diff.lineNumber.background.removed()}
|
||||
fg={themeV2.text.default}
|
||||
addedBg={themeV2.diff.background.added}
|
||||
removedBg={themeV2.diff.background.removed}
|
||||
contextBg={themeV2.diff.background.context}
|
||||
addedSignColor={themeV2.diff.highlight.added}
|
||||
removedSignColor={themeV2.diff.highlight.removed}
|
||||
lineNumberFg={themeV2.diff.lineNumber.text}
|
||||
lineNumberBg={themeV2.diff.background.context}
|
||||
addedLineNumberBg={themeV2.diff.lineNumber.background.added}
|
||||
removedLineNumberBg={themeV2.diff.lineNumber.background.removed}
|
||||
/>
|
||||
</box>
|
||||
</Show>
|
||||
|
|
@ -2898,7 +2902,7 @@ function ApplyPatch(props: ToolProps) {
|
|||
<FilePath
|
||||
value={file.resource}
|
||||
maxWidth={Math.max(2, ctx.width - 3)}
|
||||
fg={file.type === "delete" ? themeV2.diff.text.removed() : themeV2.text.subdued()}
|
||||
fg={file.type === "delete" ? themeV2.diff.text.removed : themeV2.text.subdued}
|
||||
/>
|
||||
</BlockTool>
|
||||
)}
|
||||
|
|
@ -2945,8 +2949,8 @@ function Question(props: ToolProps) {
|
|||
<For each={questions()}>
|
||||
{(q, i) => (
|
||||
<box flexDirection="column">
|
||||
<text fg={themeV2.text.subdued()}>{q.question}</text>
|
||||
<text fg={themeV2.text()}>{format(answers()?.[i()])}</text>
|
||||
<text fg={themeV2.text.subdued}>{q.question}</text>
|
||||
<text fg={themeV2.text.default}>{format(answers()?.[i()])}</text>
|
||||
</box>
|
||||
)}
|
||||
</For>
|
||||
|
|
@ -2987,7 +2991,7 @@ function Diagnostics(props: { diagnostics: unknown; filePath: string }) {
|
|||
<box>
|
||||
<For each={errors()}>
|
||||
{(diagnostic) => (
|
||||
<text fg={themeV2.text.feedback.error()}>
|
||||
<text fg={themeV2.text.feedback.error.default}>
|
||||
Error [{diagnostic.range.start.line + 1}:{diagnostic.range.start.character + 1}] {diagnostic.message}
|
||||
</text>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@ function EditBody(props: { file?: string; diff?: string; patch?: string }) {
|
|||
scrollAcceleration={scrollAcceleration()}
|
||||
verticalScrollbarOptions={{
|
||||
trackOptions: {
|
||||
backgroundColor: themeV2.background(),
|
||||
foregroundColor: themeV2.scrollbar(),
|
||||
backgroundColor: themeV2.background.default,
|
||||
foregroundColor: themeV2.scrollbar.default,
|
||||
},
|
||||
}}
|
||||
>
|
||||
|
|
@ -58,16 +58,16 @@ function EditBody(props: { file?: string; diff?: string; patch?: string }) {
|
|||
showLineNumbers={true}
|
||||
width="100%"
|
||||
wrapMode="word"
|
||||
fg={themeV2.text()}
|
||||
addedBg={themeV2.diff.background.added()}
|
||||
removedBg={themeV2.diff.background.removed()}
|
||||
contextBg={themeV2.diff.background.context()}
|
||||
addedSignColor={themeV2.diff.highlight.added()}
|
||||
removedSignColor={themeV2.diff.highlight.removed()}
|
||||
lineNumberFg={themeV2.diff.lineNumber.text()}
|
||||
lineNumberBg={themeV2.diff.background.context()}
|
||||
addedLineNumberBg={themeV2.diff.lineNumber.background.added()}
|
||||
removedLineNumberBg={themeV2.diff.lineNumber.background.removed()}
|
||||
fg={themeV2.text.default}
|
||||
addedBg={themeV2.diff.background.added}
|
||||
removedBg={themeV2.diff.background.removed}
|
||||
contextBg={themeV2.diff.background.context}
|
||||
addedSignColor={themeV2.diff.highlight.added}
|
||||
removedSignColor={themeV2.diff.highlight.removed}
|
||||
lineNumberFg={themeV2.diff.lineNumber.text}
|
||||
lineNumberBg={themeV2.diff.background.context}
|
||||
addedLineNumberBg={themeV2.diff.lineNumber.background.added}
|
||||
removedLineNumberBg={themeV2.diff.lineNumber.background.removed}
|
||||
/>
|
||||
</scrollbox>
|
||||
</Show>
|
||||
|
|
@ -76,7 +76,7 @@ function EditBody(props: { file?: string; diff?: string; patch?: string }) {
|
|||
when={props.patch}
|
||||
fallback={
|
||||
<box paddingLeft={1}>
|
||||
<text fg={themeV2.text.subdued()}>No diff provided</text>
|
||||
<text fg={themeV2.text.subdued}>No diff provided</text>
|
||||
</box>
|
||||
}
|
||||
>
|
||||
|
|
@ -86,8 +86,8 @@ function EditBody(props: { file?: string; diff?: string; patch?: string }) {
|
|||
scrollAcceleration={scrollAcceleration()}
|
||||
verticalScrollbarOptions={{
|
||||
trackOptions: {
|
||||
backgroundColor: themeV2.background(),
|
||||
foregroundColor: themeV2.scrollbar(),
|
||||
backgroundColor: themeV2.background.default,
|
||||
foregroundColor: themeV2.scrollbar.default,
|
||||
},
|
||||
}}
|
||||
>
|
||||
|
|
@ -97,7 +97,7 @@ function EditBody(props: { file?: string; diff?: string; patch?: string }) {
|
|||
streaming={true}
|
||||
syntaxStyle={syntax()}
|
||||
content={patch()}
|
||||
fg={themeV2.text.subdued()}
|
||||
fg={themeV2.text.subdued}
|
||||
/>
|
||||
</scrollbox>
|
||||
)}
|
||||
|
|
@ -140,7 +140,7 @@ export function PermissionPrompt(props: { request: PermissionV2Request; director
|
|||
body={
|
||||
<box paddingLeft={1} gap={1}>
|
||||
<For each={permissionAlwaysLines(props.request)}>
|
||||
{(line, index) => <text fg={index() === 0 ? themeV2.text.subdued() : themeV2.text()}>{line}</text>}
|
||||
{(line, index) => <text fg={index() === 0 ? themeV2.text.subdued : themeV2.text.default}>{line}</text>}
|
||||
</For>
|
||||
</box>
|
||||
}
|
||||
|
|
@ -192,9 +192,9 @@ export function PermissionPrompt(props: { request: PermissionV2Request; director
|
|||
) : props.request.action === "external_directory" ? (
|
||||
<Show when={current.lines.length > 0}>
|
||||
<box paddingLeft={1} gap={1}>
|
||||
<text fg={themeV2.text.subdued()}>Patterns</text>
|
||||
<text fg={themeV2.text.subdued}>Patterns</text>
|
||||
<box>
|
||||
<For each={current.lines}>{(line) => <text fg={themeV2.text()}>{line}</text>}</For>
|
||||
<For each={current.lines}>{(line) => <text fg={themeV2.text.default}>{line}</text>}</For>
|
||||
</box>
|
||||
</box>
|
||||
</Show>
|
||||
|
|
@ -207,8 +207,8 @@ export function PermissionPrompt(props: { request: PermissionV2Request; director
|
|||
props.request.action === "shell" ||
|
||||
props.request.action === "subagent" ||
|
||||
props.request.action === "task"
|
||||
? themeV2.text()
|
||||
: themeV2.text.subdued()
|
||||
? themeV2.text.default
|
||||
: themeV2.text.subdued
|
||||
}
|
||||
>
|
||||
{line}
|
||||
|
|
@ -221,15 +221,15 @@ export function PermissionPrompt(props: { request: PermissionV2Request; director
|
|||
const header = () => (
|
||||
<box flexDirection="column" gap={0}>
|
||||
<box flexDirection="row" gap={1} flexShrink={0}>
|
||||
<text fg={themeV2.text.feedback.warning()}>{"△"}</text>
|
||||
<text fg={themeV2.text()}>Permission required</text>
|
||||
<text fg={themeV2.text.feedback.warning.default}>{"△"}</text>
|
||||
<text fg={themeV2.text.default}>Permission required</text>
|
||||
</box>
|
||||
<Show when={props.request.action !== "shell" && current.title}>
|
||||
<box flexDirection="row" gap={1} paddingLeft={2} flexShrink={0}>
|
||||
<text fg={themeV2.text.subdued()} flexShrink={0}>
|
||||
<text fg={themeV2.text.subdued} flexShrink={0}>
|
||||
{current.icon}
|
||||
</text>
|
||||
<text fg={themeV2.text()}>{current.title}</text>
|
||||
<text fg={themeV2.text.default}>{current.title}</text>
|
||||
</box>
|
||||
</Show>
|
||||
</box>
|
||||
|
|
@ -329,18 +329,18 @@ function RejectPrompt(props: {
|
|||
role: "dialog",
|
||||
label: `Reject permission: ${props.action}`,
|
||||
}))}
|
||||
backgroundColor={themeV2.background()}
|
||||
backgroundColor={themeV2.background.default}
|
||||
border={["left"]}
|
||||
borderColor={themeV2.text.feedback.error()}
|
||||
borderColor={themeV2.text.feedback.error.default}
|
||||
customBorderChars={SplitBorder.customBorderChars}
|
||||
>
|
||||
<box gap={1} paddingLeft={1} paddingRight={3} paddingTop={1} paddingBottom={1}>
|
||||
<box flexDirection="row" gap={1} paddingLeft={1}>
|
||||
<text fg={themeV2.text.feedback.error()}>{"△"}</text>
|
||||
<text fg={themeV2.text()}>Reject permission</text>
|
||||
<text fg={themeV2.text.feedback.error.default}>{"△"}</text>
|
||||
<text fg={themeV2.text.default}>Reject permission</text>
|
||||
</box>
|
||||
<box paddingLeft={1}>
|
||||
<text fg={themeV2.text.subdued()}>Tell OpenCode what to do differently</text>
|
||||
<text fg={themeV2.text.subdued}>Tell OpenCode what to do differently</text>
|
||||
</box>
|
||||
</box>
|
||||
<box
|
||||
|
|
@ -350,7 +350,7 @@ function RejectPrompt(props: {
|
|||
paddingLeft={2}
|
||||
paddingRight={3}
|
||||
paddingBottom={1}
|
||||
backgroundColor={themeV2.raise(themeV2.background())}
|
||||
backgroundColor={themeV2.raise(themeV2.background.default)}
|
||||
justifyContent={narrow() ? "flex-start" : "space-between"}
|
||||
alignItems={narrow() ? "flex-start" : "center"}
|
||||
gap={1}
|
||||
|
|
@ -369,9 +369,9 @@ function RejectPrompt(props: {
|
|||
val.traits = { status: "REJECT" }
|
||||
}}
|
||||
focused
|
||||
textColor={themeV2.text()}
|
||||
focusedTextColor={themeV2.text()}
|
||||
cursorColor={themeV2.text()}
|
||||
textColor={themeV2.text.default}
|
||||
focusedTextColor={themeV2.text.default}
|
||||
cursorColor={themeV2.text.default}
|
||||
/>
|
||||
<box
|
||||
id="session.permission.reject.actions"
|
||||
|
|
@ -394,8 +394,8 @@ function RejectPrompt(props: {
|
|||
}))}
|
||||
onMouseUp={() => props.onConfirm(input.plainText)}
|
||||
>
|
||||
<text fg={themeV2.text()}>
|
||||
enter <span style={{ fg: themeV2.text.subdued() }}>confirm</span>
|
||||
<text fg={themeV2.text.default}>
|
||||
enter <span style={{ fg: themeV2.text.subdued }}>confirm</span>
|
||||
</text>
|
||||
</box>
|
||||
<box
|
||||
|
|
@ -408,8 +408,8 @@ function RejectPrompt(props: {
|
|||
}))}
|
||||
onMouseUp={props.onCancel}
|
||||
>
|
||||
<text fg={themeV2.text()}>
|
||||
esc <span style={{ fg: themeV2.text.subdued() }}>cancel</span>
|
||||
<text fg={themeV2.text.default}>
|
||||
esc <span style={{ fg: themeV2.text.subdued }}>cancel</span>
|
||||
</text>
|
||||
</box>
|
||||
</box>
|
||||
|
|
@ -534,9 +534,9 @@ function Prompt<const T extends Record<string, string>>(props: {
|
|||
label: props.semanticLabel ?? props.title,
|
||||
expanded: store.expanded,
|
||||
}))}
|
||||
backgroundColor={themeV2.background()}
|
||||
backgroundColor={themeV2.background.default}
|
||||
border={["left"]}
|
||||
borderColor={themeV2.background.action("focused")}
|
||||
borderColor={themeV2.background.action.primary.focused}
|
||||
customBorderChars={SplitBorder.customBorderChars}
|
||||
{...(store.expanded
|
||||
? { top: dimensions().height * -1 + 1, bottom: 1, left: 2, right: 2, position: "absolute" }
|
||||
|
|
@ -554,8 +554,8 @@ function Prompt<const T extends Record<string, string>>(props: {
|
|||
when={props.header}
|
||||
fallback={
|
||||
<box flexDirection="row" gap={1} paddingLeft={1} flexShrink={0}>
|
||||
<text fg={themeV2.text.feedback.warning()}>{"△"}</text>
|
||||
<text fg={themeV2.text()}>{props.title}</text>
|
||||
<text fg={themeV2.text.feedback.warning.default}>{"△"}</text>
|
||||
<text fg={themeV2.text.default}>{props.title}</text>
|
||||
</box>
|
||||
}
|
||||
>
|
||||
|
|
@ -573,7 +573,7 @@ function Prompt<const T extends Record<string, string>>(props: {
|
|||
paddingLeft={2}
|
||||
paddingRight={3}
|
||||
paddingBottom={1}
|
||||
backgroundColor={themeV2.raise(themeV2.background())}
|
||||
backgroundColor={themeV2.raise(themeV2.background.default)}
|
||||
justifyContent={narrow() ? "flex-start" : "space-between"}
|
||||
alignItems={narrow() ? "flex-start" : "center"}
|
||||
>
|
||||
|
|
@ -602,14 +602,24 @@ function Prompt<const T extends Record<string, string>>(props: {
|
|||
}))}
|
||||
paddingLeft={1}
|
||||
paddingRight={1}
|
||||
backgroundColor={themeV2.background.action(option === store.selected ? "focused" : "default")}
|
||||
backgroundColor={
|
||||
option === store.selected
|
||||
? themeV2.background.action.primary.focused
|
||||
: themeV2.background.action.primary.default
|
||||
}
|
||||
onMouseOver={() => setStore("selected", option)}
|
||||
onMouseUp={() => {
|
||||
setStore("selected", option)
|
||||
props.onSelect(option)
|
||||
}}
|
||||
>
|
||||
<text fg={themeV2.text.action(option === store.selected ? "focused" : "default")}>
|
||||
<text
|
||||
fg={
|
||||
option === store.selected
|
||||
? themeV2.text.action.primary.focused
|
||||
: themeV2.text.action.primary.default
|
||||
}
|
||||
>
|
||||
{props.options[option]}
|
||||
</text>
|
||||
</box>
|
||||
|
|
@ -618,16 +628,15 @@ function Prompt<const T extends Record<string, string>>(props: {
|
|||
</box>
|
||||
<box flexDirection="row" gap={2} flexShrink={0}>
|
||||
<Show when={props.fullscreen}>
|
||||
<text fg={themeV2.text()}>
|
||||
{shortcuts.get("permission.prompt.fullscreen")}{" "}
|
||||
<span style={{ fg: themeV2.text.subdued() }}>{hint()}</span>
|
||||
<text fg={themeV2.text.default}>
|
||||
{shortcuts.get("permission.prompt.fullscreen")} <span style={{ fg: themeV2.text.subdued }}>{hint()}</span>
|
||||
</text>
|
||||
</Show>
|
||||
<text fg={themeV2.text()}>
|
||||
{"⇆"} <span style={{ fg: themeV2.text.subdued() }}>select</span>
|
||||
<text fg={themeV2.text.default}>
|
||||
{"⇆"} <span style={{ fg: themeV2.text.subdued }}>select</span>
|
||||
</text>
|
||||
<text fg={themeV2.text()}>
|
||||
enter <span style={{ fg: themeV2.text.subdued() }}>confirm</span>
|
||||
<text fg={themeV2.text.default}>
|
||||
enter <span style={{ fg: themeV2.text.subdued }}>confirm</span>
|
||||
</text>
|
||||
</box>
|
||||
</box>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ export function Sidebar(props: { sessionID: string; overlay?: boolean }) {
|
|||
return (
|
||||
<Show when={session()}>
|
||||
<box
|
||||
backgroundColor={themeV2.background()}
|
||||
backgroundColor={themeV2.background.default}
|
||||
width={42}
|
||||
height="100%"
|
||||
paddingTop={1}
|
||||
|
|
@ -32,8 +32,8 @@ export function Sidebar(props: { sessionID: string; overlay?: boolean }) {
|
|||
scrollAcceleration={scrollAcceleration()}
|
||||
verticalScrollbarOptions={{
|
||||
trackOptions: {
|
||||
backgroundColor: themeV2.background(),
|
||||
foregroundColor: themeV2.scrollbar(),
|
||||
backgroundColor: themeV2.background.default,
|
||||
foregroundColor: themeV2.scrollbar.default,
|
||||
},
|
||||
}}
|
||||
>
|
||||
|
|
@ -45,11 +45,11 @@ export function Sidebar(props: { sessionID: string; overlay?: boolean }) {
|
|||
title={session()!.title}
|
||||
>
|
||||
<box paddingRight={1}>
|
||||
<text fg={themeV2.text()}>
|
||||
<text fg={themeV2.text.default}>
|
||||
<b>{session()!.title}</b>
|
||||
</text>
|
||||
<Show when={session()!.location.workspaceID}>
|
||||
<text fg={themeV2.text.subdued()}>{session()!.location.workspaceID}</text>
|
||||
<text fg={themeV2.text.subdued}>{session()!.location.workspaceID}</text>
|
||||
</Show>
|
||||
</box>
|
||||
</pluginRuntime.Slot>
|
||||
|
|
|
|||
|
|
@ -61,18 +61,18 @@ export function SubagentFooter() {
|
|||
paddingRight={1}
|
||||
{...SplitBorder}
|
||||
border={["left"]}
|
||||
borderColor={themeV2.border()}
|
||||
borderColor={themeV2.border.default}
|
||||
flexShrink={0}
|
||||
backgroundColor={themeV2.background()}
|
||||
backgroundColor={themeV2.background.default}
|
||||
>
|
||||
<box flexDirection="row" justifyContent="space-between" gap={1}>
|
||||
<box flexDirection="row" gap={1}>
|
||||
<text fg={themeV2.text()}>
|
||||
<text fg={themeV2.text.default}>
|
||||
<b>{subagentInfo()}</b>
|
||||
</text>
|
||||
<Show when={usage()}>
|
||||
{(item) => (
|
||||
<text fg={themeV2.text.subdued()} wrapMode="none">
|
||||
<text fg={themeV2.text.subdued} wrapMode="none">
|
||||
{[item().context, item().cost].filter(Boolean).join(" · ")}
|
||||
</text>
|
||||
)}
|
||||
|
|
@ -83,30 +83,36 @@ export function SubagentFooter() {
|
|||
onMouseOver={() => setHover("parent")}
|
||||
onMouseOut={() => setHover(null)}
|
||||
onMouseUp={() => keymap.dispatch("session.parent")}
|
||||
backgroundColor={hover() === "parent" ? themeV2.background.action("hovered") : themeV2.background()}
|
||||
backgroundColor={
|
||||
hover() === "parent" ? themeV2.background.action.primary.hovered : themeV2.background.default
|
||||
}
|
||||
>
|
||||
<text fg={themeV2.text()}>
|
||||
Parent <span style={{ fg: themeV2.text.subdued() }}>{shortcuts.get("session.parent")}</span>
|
||||
<text fg={themeV2.text.default}>
|
||||
Parent <span style={{ fg: themeV2.text.subdued }}>{shortcuts.get("session.parent")}</span>
|
||||
</text>
|
||||
</box>
|
||||
<box
|
||||
onMouseOver={() => setHover("prev")}
|
||||
onMouseOut={() => setHover(null)}
|
||||
onMouseUp={() => keymap.dispatch("session.child.previous")}
|
||||
backgroundColor={hover() === "prev" ? themeV2.background.action("hovered") : themeV2.background()}
|
||||
backgroundColor={
|
||||
hover() === "prev" ? themeV2.background.action.primary.hovered : themeV2.background.default
|
||||
}
|
||||
>
|
||||
<text fg={themeV2.text()}>
|
||||
Prev <span style={{ fg: themeV2.text.subdued() }}>{shortcuts.get("session.child.previous")}</span>
|
||||
<text fg={themeV2.text.default}>
|
||||
Prev <span style={{ fg: themeV2.text.subdued }}>{shortcuts.get("session.child.previous")}</span>
|
||||
</text>
|
||||
</box>
|
||||
<box
|
||||
onMouseOver={() => setHover("next")}
|
||||
onMouseOut={() => setHover(null)}
|
||||
onMouseUp={() => keymap.dispatch("session.child.next")}
|
||||
backgroundColor={hover() === "next" ? themeV2.background.action("hovered") : themeV2.background()}
|
||||
backgroundColor={
|
||||
hover() === "next" ? themeV2.background.action.primary.hovered : themeV2.background.default
|
||||
}
|
||||
>
|
||||
<text fg={themeV2.text()}>
|
||||
Next <span style={{ fg: themeV2.text.subdued() }}>{shortcuts.get("session.child.next")}</span>
|
||||
<text fg={themeV2.text.default}>
|
||||
Next <span style={{ fg: themeV2.text.subdued }}>{shortcuts.get("session.child.next")}</span>
|
||||
</text>
|
||||
</box>
|
||||
</box>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue