Merge branch 'dev' into sqlite2

This commit is contained in:
Dax Raad
2026-02-04 22:37:08 -05:00
138 changed files with 3658 additions and 1600 deletions
+6 -1
View File
@@ -277,6 +277,11 @@ export const RunCommand = cmd({
type: "string",
describe: "model variant (provider-specific reasoning effort, e.g., high, max, minimal)",
})
.option("thinking", {
type: "boolean",
describe: "show thinking blocks",
default: false,
})
},
handler: async (args) => {
let message = [...args.message, ...(args["--"] || [])]
@@ -455,7 +460,7 @@ export const RunCommand = cmd({
UI.empty()
}
if (part.type === "reasoning" && part.time?.end) {
if (part.type === "reasoning" && part.time?.end && args.thinking) {
if (emit("reasoning", { part })) continue
const text = part.text.trim()
if (!text) continue
@@ -187,7 +187,6 @@ function App() {
const route = useRoute()
const dimensions = useTerminalDimensions()
const renderer = useRenderer()
Clipboard.setRenderer(renderer)
renderer.disableStdoutInterception()
const dialog = useDialog()
const local = useLocal()
@@ -35,6 +35,7 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
const agent = iife(() => {
const agents = createMemo(() => sync.data.agent.filter((x) => x.mode !== "subagent" && !x.hidden))
const visibleAgents = createMemo(() => sync.data.agent.filter((x) => !x.hidden))
const [agentStore, setAgentStore] = createStore<{
current: string
}>({
@@ -48,6 +49,7 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
theme.warning,
theme.primary,
theme.error,
theme.info,
])
return {
list() {
@@ -75,11 +77,16 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
})
},
color(name: string) {
const all = sync.data.agent
const agent = all.find((x) => x.name === name)
if (agent?.color) return RGBA.fromHex(agent.color)
const index = all.findIndex((x) => x.name === name)
const index = visibleAgents().findIndex((x) => x.name === name)
if (index === -1) return colors()[0]
const agent = visibleAgents()[index]
if (agent?.color) {
const color = agent.color
if (color.startsWith("#")) return RGBA.fromHex(color)
// already validated by config, just satisfying TS here
return theme[color as keyof typeof theme] as RGBA
}
return colors()[index % colors().length]
},
}
@@ -546,6 +546,7 @@ export function Session() {
{
title: showThinking() ? "Hide thinking" : "Show thinking",
value: "session.toggle.thinking",
keybind: "display_thinking",
category: "Session",
slash: {
name: "thinking",
@@ -1,5 +1,5 @@
import { createStore } from "solid-js/store"
import { createMemo, For, Show } from "solid-js"
import { createMemo, createSignal, For, Show } from "solid-js"
import { useKeyboard } from "@opentui/solid"
import type { TextareaRenderable } from "@opentui/core"
import { useKeybind } from "../../context/keybind"
@@ -19,6 +19,7 @@ export function QuestionPrompt(props: { request: QuestionRequest }) {
const questions = createMemo(() => props.request.questions)
const single = createMemo(() => questions().length === 1 && questions()[0]?.multiple !== true)
const tabs = createMemo(() => (single() ? 1 : questions().length + 1)) // questions + confirm tab (no confirm for single select)
const [tabHover, setTabHover] = createSignal<number | "confirm" | null>(null)
const [store, setStore] = createStore({
tab: 0,
answers: [] as QuestionAnswer[],
@@ -269,7 +270,15 @@ export function QuestionPrompt(props: { request: QuestionRequest }) {
<box
paddingLeft={1}
paddingRight={1}
backgroundColor={isActive() ? theme.accent : theme.backgroundElement}
backgroundColor={
isActive()
? theme.accent
: tabHover() === index()
? theme.backgroundElement
: theme.backgroundPanel
}
onMouseOver={() => setTabHover(index())}
onMouseOut={() => setTabHover(null)}
onMouseUp={() => selectTab(index())}
>
<text
@@ -290,7 +299,11 @@ export function QuestionPrompt(props: { request: QuestionRequest }) {
<box
paddingLeft={1}
paddingRight={1}
backgroundColor={confirm() ? theme.accent : theme.backgroundElement}
backgroundColor={
confirm() ? theme.accent : tabHover() === "confirm" ? theme.backgroundElement : theme.backgroundPanel
}
onMouseOver={() => setTabHover("confirm")}
onMouseOut={() => setTabHover(null)}
onMouseUp={() => selectTab(questions().length)}
>
<text fg={confirm() ? selectedForeground(theme, theme.accent) : theme.textMuted}>Confirm</text>
@@ -1,12 +1,23 @@
import { $ } from "bun"
import type { CliRenderer } from "@opentui/core"
import { platform, release } from "os"
import clipboardy from "clipboardy"
import { lazy } from "../../../../util/lazy.js"
import { tmpdir } from "os"
import path from "path"
const rendererRef = { current: undefined as CliRenderer | undefined }
/**
* Writes text to clipboard via OSC 52 escape sequence.
* This allows clipboard operations to work over SSH by having
* the terminal emulator handle the clipboard locally.
*/
function writeOsc52(text: string): void {
if (!process.stdout.isTTY) return
const base64 = Buffer.from(text).toString("base64")
const osc52 = `\x1b]52;c;${base64}\x07`
const passthrough = process.env["TMUX"] || process.env["STY"]
const sequence = passthrough ? `\x1bPtmux;\x1b${osc52}\x1b\\` : osc52
process.stdout.write(sequence)
}
export namespace Clipboard {
export interface Content {
@@ -14,10 +25,6 @@ export namespace Clipboard {
mime: string
}
export function setRenderer(renderer: CliRenderer | undefined): void {
rendererRef.current = renderer
}
export async function read(): Promise<Content | undefined> {
const os = platform()
@@ -146,11 +153,7 @@ export namespace Clipboard {
})
export async function copy(text: string): Promise<void> {
const renderer = rendererRef.current
if (renderer) {
const copied = renderer.copyToClipboardOSC52(text)
if (copied) return
}
writeOsc52(text)
await getCopyMethod()(text)
}
}