Skip to content

Commit 00a653a

Browse files
committed
ci/cd fucks, /help updates, error windows rewamp
1 parent 9f007b7 commit 00a653a

8 files changed

Lines changed: 323 additions & 32 deletions

File tree

packages/desktop/scripts/finalize-latest-json.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ async function resolveTauriSigningKey() {
114114
const value = process.env.TAURI_SIGNING_PRIVATE_KEY
115115
if (!value) throw new Error("TAURI_SIGNING_PRIVATE_KEY is required")
116116

117+
const encodeMinisignKey = (input: string) => Buffer.from(input, "utf8").toString("base64")
118+
117119
const normalizeMinisignKey = (input: string) => {
118120
const lines = input
119121
.replaceAll("\r\n", "\n")
@@ -146,19 +148,25 @@ async function resolveTauriSigningKey() {
146148
"TAURI_SIGNING_PRIVATE_KEY file must contain a minisign private key. The first line should start with 'untrusted comment:'.",
147149
)
148150
}
149-
process.env.TAURI_SIGNING_PRIVATE_KEY = text
151+
process.env.TAURI_SIGNING_PRIVATE_KEY = encodeMinisignKey(text)
152+
return process.env.TAURI_SIGNING_PRIVATE_KEY
153+
}
154+
155+
const decoded = normalizeMinisignKey(value)
156+
if (decoded) {
157+
process.env.TAURI_SIGNING_PRIVATE_KEY = encodeMinisignKey(decoded)
150158
return process.env.TAURI_SIGNING_PRIVATE_KEY
151159
}
152160

153-
const decoded = normalizeMinisignKey(value) ?? normalizeEncodedKey(value)
161+
const encoded = normalizeEncodedKey(value)
154162

155-
if (!decoded) {
163+
if (!encoded) {
156164
throw new Error(
157165
"TAURI_SIGNING_PRIVATE_KEY must be a minisign private key or a path to one. The first line should start with 'untrusted comment:'.",
158166
)
159167
}
160168

161-
process.env.TAURI_SIGNING_PRIVATE_KEY = decoded
169+
process.env.TAURI_SIGNING_PRIVATE_KEY = encodeMinisignKey(encoded)
162170
return process.env.TAURI_SIGNING_PRIVATE_KEY
163171
}
164172

packages/opencode/src/cli/cmd/tui/app.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,7 @@ function App(props: { onSnapshot?: () => Promise<string[]> }) {
661661
name: "help",
662662
},
663663
onSelect: () => {
664-
dialog.replace(() => <DialogHelp />)
664+
dialog.replace(() => <DialogHelp commands={command.list()} />)
665665
},
666666
category: "System",
667667
},

packages/opencode/src/cli/cmd/tui/component/dialog-command.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ function init() {
7575
})
7676

7777
const result = {
78+
list() {
79+
return visibleOptions()
80+
},
7881
trigger(name: string) {
7982
for (const option of entries()) {
8083
if (option.value === name) {

packages/opencode/src/cli/cmd/tui/component/error-component.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import { TextAttributes } from "@opentui/core"
22
import { useKeyboard, useRenderer, useTerminalDimensions } from "@opentui/solid"
3+
import * as Clipboard from "@tui/util/clipboard"
34
import { win32FlushInputBuffer } from "../win32"
45
import { getScrollAcceleration } from "../util/scroll"
6+
import { createSignal } from "solid-js"
57

68
export function ErrorComponent(props: {
79
error: Error
@@ -12,6 +14,7 @@ export function ErrorComponent(props: {
1214
}) {
1315
const term = useTerminalDimensions()
1416
const renderer = useRenderer()
17+
const [copied, setCopied] = createSignal(false)
1518

1619
const handleExit = async () => {
1720
await props.onBeforeExit?.()
@@ -21,9 +24,22 @@ export function ErrorComponent(props: {
2124
await props.onExit()
2225
}
2326

27+
const errorText = () => [props.error.message, props.error.stack].filter(Boolean).join("\n\n")
28+
const handleCopy = async () => {
29+
await Clipboard.copy(errorText()).catch(() => {})
30+
setCopied(true)
31+
setTimeout(() => setCopied(false), 2000)
32+
}
33+
2434
useKeyboard((evt) => {
2535
if (evt.ctrl && evt.name === "c") {
2636
void handleExit()
37+
return
38+
}
39+
if (evt.name === "y") {
40+
evt.preventDefault()
41+
evt.stopPropagation()
42+
void handleCopy()
2743
}
2844
})
2945

@@ -42,13 +58,17 @@ export function ErrorComponent(props: {
4258
<text attributes={TextAttributes.BOLD} fg={colors.text}>
4359
A fatal error occurred!
4460
</text>
61+
<box onMouseUp={() => void handleCopy()} backgroundColor={colors.primary} padding={1}>
62+
<text fg={colors.bg}>Copy error</text>
63+
</box>
4564
<box onMouseUp={props.reset} backgroundColor={colors.primary} padding={1}>
4665
<text fg={colors.bg}>Reset TUI</text>
4766
</box>
4867
<box onMouseUp={handleExit} backgroundColor={colors.primary} padding={1}>
4968
<text fg={colors.bg}>Exit</text>
5069
</box>
5170
</box>
71+
<text fg={colors.muted}>{copied() ? "Error copied to clipboard" : "Press Y to copy the full error log"}</text>
5272
<scrollbox height={Math.floor(term().height * 0.7)} scrollAcceleration={getScrollAcceleration()}>
5373
<text fg={colors.muted}>{props.error.stack}</text>
5474
</scrollbox>

packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,10 +359,11 @@ export function Prompt(props: PromptProps) {
359359
extmarkToPartIndex: new Map(),
360360
interrupt: 0,
361361
})
362-
const showThinking = createMemo(() => local.model.parsed().reasoning && store.mode === "normal")
362+
const showThinking = createMemo(() => local.model.variant.supportsThinking() && store.mode === "normal")
363363
const visibleVariantLabel = createMemo(() => {
364364
const value = variantLabel()
365365
if (!value) return
366+
if (value.toLowerCase() === "default") return
366367
if (showThinking() && THINKING_DISPLAY_VARIANTS.has(value.toLowerCase())) return
367368
return value
368369
})

packages/opencode/src/cli/cmd/tui/context/local.tsx

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,21 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
353353
if (variants.length === 0) return false
354354
return variants.every(([name, options]) => thinkingState(options, name) !== "inherit")
355355
}
356+
const thinkingLevels = () => {
357+
const thinking = resolveThinking()
358+
if (!thinking) return []
359+
if (thinking.hasThinkingToggle && thinking.levelVariant.high === "thinking") {
360+
return ["off", "high"] as ThinkingLevel[]
361+
}
362+
return THINKING_LEVELS.filter((level) => {
363+
if (level === "off") {
364+
return Boolean(
365+
thinking.levelVariant.off || thinking.baseLevel === "off" || thinking.defaultLevel === "off",
366+
)
367+
}
368+
return Boolean(thinking.levelVariant[level] || thinking.levels.includes(level))
369+
})
370+
}
356371

357372
return {
358373
current: currentModel,
@@ -568,6 +583,9 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
568583
}
569584
return thinking.activeLevel
570585
},
586+
supportsThinking() {
587+
return thinkingLevels().length > 1
588+
},
571589
cycleThinking() {
572590
const thinking = resolveThinking()
573591
if (!thinking) {
@@ -578,17 +596,7 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
578596
})
579597
return
580598
}
581-
const levels =
582-
thinking.hasThinkingToggle && thinking.levelVariant.high === "thinking"
583-
? (["off", "high"] as ThinkingLevel[])
584-
: THINKING_LEVELS.filter((level) => {
585-
if (level === "off") {
586-
return Boolean(
587-
thinking.levelVariant.off || thinking.baseLevel === "off" || thinking.defaultLevel === "off",
588-
)
589-
}
590-
return Boolean(thinking.levelVariant[level] || thinking.levels.includes(level))
591-
})
599+
const levels = thinkingLevels()
592600
if (levels.length === 0) return
593601
const index = levels.indexOf(thinking.activeLevel)
594602
const next = levels[(index + 1) % levels.length] ?? levels[0]

0 commit comments

Comments
 (0)