| author | |
| committer | |
| log | 24b711b7f9ccba03518551991e466e2e4f8ace5a |
| tree | 6c24bee2746e6ac2b52feb608580ebbd7488a61b |
| parent | 438465d6b7dd2e50dd38862a0db1252d2d72ecfc |
| signature | Signed by PGP key B5690EEEBB952194 |
6 files changed, 36 insertions(+), 23 deletions(-)
apps/mobile/modules/t3-terminal/ios/T3TerminalView.swift+1| ... | @@ -410,6 +410,7 @@ public final class T3TerminalView: ExpoView, UITextFieldDelegate { | ... | @@ -410,6 +410,7 @@ public final class T3TerminalView: ExpoView, UITextFieldDelegate { |
| 410 | return false | 410 | return false |
| 411 | } | 411 | } |
| 412 | 412 | ||
| 413 | emitInput("\u{7F}") | ||
| 413 | return false | 414 | return false |
| 414 | } | 415 | } |
| 415 | 416 |
apps/server/src/sourceControl/ForgejoCli.ts+23-19| ... | @@ -366,25 +366,6 @@ export const make = Effect.gen(function* () { | ... | @@ -366,25 +366,6 @@ export const make = Effect.gen(function* () { |
| 366 | .execute(request) | 366 | .execute(request) |
| 367 | .pipe(Effect.provideService(FetchHttpClient.RequestInit, { redirect: "manual" })); | 367 | .pipe(Effect.provideService(FetchHttpClient.RequestInit, { redirect: "manual" })); |
| 368 | const status = response.status; | 368 | const status = response.status; |
| 369 | if (status < 200 || status >= 300) | ||
| 370 | return yield* new ForgejoCliError({ | ||
| 371 | command: "fj", | ||
| 372 | cwd: input.cwd, | ||
| 373 | httpStatus: status, | ||
| 374 | ...(status === 401 | ||
| 375 | ? { reason: "authentication" as const } | ||
| 376 | : status === 403 | ||
| 377 | ? { reason: "forbidden" as const } | ||
| 378 | : status === 404 | ||
| 379 | ? { reason: "not-found" as const } | ||
| 380 | : status === 429 | ||
| 381 | ? { reason: "rate-limit" as const } | ||
| 382 | : {}), | ||
| 383 | detail: | ||
| 384 | status === 404 | ||
| 385 | ? "Forgejo repository or pull request was not found." | ||
| 386 | : `Forgejo API request failed (HTTP ${status}). Check this server's fj credentials and permissions.`, | ||
| 387 | }); | ||
| 388 | const body = | 369 | const body = |
| 389 | status === 204 || status === 205 | 370 | status === 204 || status === 205 |
| 390 | ? { text: "", truncated: false, invalidUtf8: false } | 371 | ? { text: "", truncated: false, invalidUtf8: false } |
| ... | @@ -399,6 +380,29 @@ export const make = Effect.gen(function* () { | ... | @@ -399,6 +380,29 @@ export const make = Effect.gen(function* () { |
| 399 | reason: "invalid-response", | 380 | reason: "invalid-response", |
| 400 | detail: "Forgejo returned an oversized or invalid response.", | 381 | detail: "Forgejo returned an oversized or invalid response.", |
| 401 | }); | 382 | }); |
| 383 | if (status < 200 || status >= 300) { | ||
| 384 | const detail = | ||
| 385 | status === 404 | ||
| 386 | ? "Forgejo repository or pull request was not found." | ||
| 387 | : body.text | ||
| 388 | ? `Forgejo API request failed (HTTP ${status}): ${body.text}` | ||
| 389 | : `Forgejo API request failed (HTTP ${status}). Check this server's fj credentials and permissions.`; | ||
| 390 | return yield* new ForgejoCliError({ | ||
| 391 | command: "fj", | ||
| 392 | cwd: input.cwd, | ||
| 393 | httpStatus: status, | ||
| 394 | ...(status === 401 | ||
| 395 | ? { reason: "authentication" as const } | ||
| 396 | : status === 403 | ||
| 397 | ? { reason: "forbidden" as const } | ||
| 398 | : status === 404 | ||
| 399 | ? { reason: "not-found" as const } | ||
| 400 | : status === 429 | ||
| 401 | ? { reason: "rate-limit" as const } | ||
| 402 | : {}), | ||
| 403 | detail, | ||
| 404 | }); | ||
| 405 | } | ||
| 402 | return { | 406 | return { |
| 403 | exitCode: ChildProcessSpawner.ExitCode(0), | 407 | exitCode: ChildProcessSpawner.ExitCode(0), |
| 404 | stdout: body.text, | 408 | stdout: body.text, |
apps/web/src/components/chat/ModelPickerSidebar.tsx+1-1| ... | @@ -203,7 +203,7 @@ export const ModelPickerSidebar = memo(function ModelPickerSidebar(props: { | ... | @@ -203,7 +203,7 @@ export const ModelPickerSidebar = memo(function ModelPickerSidebar(props: { |
| 203 | displayName={entry.displayName} | 203 | displayName={entry.displayName} |
| 204 | accentColor={entry.accentColor} | 204 | accentColor={entry.accentColor} |
| 205 | showBadge={showInstanceBadge} | 205 | showBadge={showInstanceBadge} |
| 206 | className="size-6" | 206 | className="size-6 z-30" |
| 207 | iconClassName="size-5" | 207 | iconClassName="size-5" |
| 208 | indicatorBackground={ | 208 | indicatorBackground={ |
| 209 | isHovered && !isDisabled | 209 | isHovered && !isDisabled |
apps/web/src/components/chat/ProviderInstanceIcon.tsx+1-1| ... | @@ -29,7 +29,7 @@ export const ProviderInstanceIcon = memo(function ProviderInstanceIcon(props: { | ... | @@ -29,7 +29,7 @@ export const ProviderInstanceIcon = memo(function ProviderInstanceIcon(props: { |
| 29 | return ( | 29 | return ( |
| 30 | <span | 30 | <span |
| 31 | className={cn( | 31 | className={cn( |
| 32 | "relative isolate inline-flex shrink-0 items-center justify-center overflow-visible", | 32 | "relative isolate z-30 inline-flex shrink-0 items-center justify-center overflow-visible", |
| 33 | props.className, | 33 | props.className, |
| 34 | )} | 34 | )} |
| 35 | style={accentStyle} | 35 | style={accentStyle} |
apps/web/src/components/chat/ProviderModelPicker.tsx+9-1| ... | @@ -25,6 +25,7 @@ import { | ... | @@ -25,6 +25,7 @@ import { |
| 25 | type ComposerControlSize, | 25 | type ComposerControlSize, |
| 26 | } from "./ComposerControl"; | 26 | } from "./ComposerControl"; |
| 27 | import { useComposerMenuProps } from "./composerEventScope"; | 27 | import { useComposerMenuProps } from "./composerEventScope"; |
| 28 | import { shortcutLabelForCommand } from "../../keybindings"; | ||
| 28 | 29 | ||
| 29 | export const ProviderModelPicker = memo(function ProviderModelPicker(props: { | 30 | export const ProviderModelPicker = memo(function ProviderModelPicker(props: { |
| 30 | /** | 31 | /** |
| ... | @@ -154,6 +155,13 @@ export const ProviderModelPicker = memo(function ProviderModelPicker(props: { | ... | @@ -154,6 +155,13 @@ export const ProviderModelPicker = memo(function ProviderModelPicker(props: { |
| 154 | setIsMenuOpen(false); | 155 | setIsMenuOpen(false); |
| 155 | }; | 156 | }; |
| 156 | 157 | ||
| 158 | const shortcutLabel = props.keybindings | ||
| 159 | ? shortcutLabelForCommand(props.keybindings, "modelPicker.toggle") | ||
| 160 | : null; | ||
| 161 | const triggerTooltipContent = shortcutLabel | ||
| 162 | ? `${props.triggerLabel ?? triggerLabel} · ${shortcutLabel}` | ||
| 163 | : (props.triggerLabel ?? triggerLabel); | ||
| 164 | |||
| 157 | return ( | 165 | return ( |
| 158 | <Popover | 166 | <Popover |
| 159 | open={isMenuOpen} | 167 | open={isMenuOpen} |
| ... | @@ -210,7 +218,7 @@ export const ProviderModelPicker = memo(function ProviderModelPicker(props: { | ... | @@ -210,7 +218,7 @@ export const ProviderModelPicker = memo(function ProviderModelPicker(props: { |
| 210 | > | 218 | > |
| 211 | {props.triggerLabel ?? triggerTitle} | 219 | {props.triggerLabel ?? triggerTitle} |
| 212 | </TooltipTrigger> | 220 | </TooltipTrigger> |
| 213 | <TooltipPopup side="top">{props.triggerLabel ?? triggerLabel}</TooltipPopup> | 221 | <TooltipPopup side="top">{triggerTooltipContent}</TooltipPopup> |
| 214 | </Tooltip> | 222 | </Tooltip> |
| 215 | {selectedModel?.isUnavailable && props.triggerLabel === undefined ? ( | 223 | {selectedModel?.isUnavailable && props.triggerLabel === undefined ? ( |
| 216 | <Badge variant="outline" size="sm"> | 224 | <Badge variant="outline" size="sm"> |
apps/web/src/components/ui/dialog-styles.ts+1-1| ... | @@ -5,7 +5,7 @@ const DIALOG_BACKDROP_CLASS = `dialog-backdrop ${DIALOG_BACKDROP_BASE_CLASS}`; | ... | @@ -5,7 +5,7 @@ const DIALOG_BACKDROP_CLASS = `dialog-backdrop ${DIALOG_BACKDROP_BASE_CLASS}`; |
| 5 | const DIALOG_MEDIA_BACKDROP_CLASS = `${DIALOG_BACKDROP_BASE_CLASS} bg-black/75 backdrop-blur-none`; | 5 | const DIALOG_MEDIA_BACKDROP_CLASS = `${DIALOG_BACKDROP_BASE_CLASS} bg-black/75 backdrop-blur-none`; |
| 6 | 6 | ||
| 7 | const DIALOG_POPUP_BASE_CLASS = | 7 | const DIALOG_POPUP_BASE_CLASS = |
| 8 | "-translate-y-[calc(1.25rem*var(--nested-dialogs))] relative flex min-h-0 w-full min-w-0 scale-[calc(1-0.1*var(--nested-dialogs))] flex-col opacity-[calc(1-0.1*var(--nested-dialogs))] outline-none transition-[scale,opacity,translate] duration-200 ease-in-out will-change-transform data-nested:data-ending-style:translate-y-8 data-nested:data-starting-style:translate-y-8 data-nested-dialog-open:origin-top data-ending-style:scale-98 data-starting-style:scale-98 data-ending-style:opacity-0 data-starting-style:opacity-0"; | 8 | "-translate-y-[calc(1.25rem*var(--nested-dialogs))] relative flex min-h-0 w-full min-w-0 scale-[calc(1-0.1*var(--nested-dialogs))] flex-col opacity-[calc(1-0.1*var(--nested-dialogs))] outline-none transition-[scale,opacity,translate] duration-200 ease-in-out will-change-transform data-nested:data-ending-style:translate-y-8 data-nested:data-starting-style:translate-y-8 data-nested-dialog-open:origin-top data-ending-style:scale-98 data-starting-style:scale-98 data-ending-style:opacity-0 data-starting-style:opacity-0 [-webkit-app-region:no-drag]"; |
| 9 | 9 | ||
| 10 | const DIALOG_POPUP_CLASS = `dialog-glass ${DIALOG_POPUP_BASE_CLASS} rounded-2xl border`; | 10 | const DIALOG_POPUP_CLASS = `dialog-glass ${DIALOG_POPUP_BASE_CLASS} rounded-2xl border`; |
| 11 | const DIALOG_MEDIA_POPUP_CLASS = `${DIALOG_POPUP_BASE_CLASS} max-h-[92vh] w-auto max-w-[92vw] overflow-visible rounded-none border border-transparent bg-transparent p-0 shadow-none`; | 11 | const DIALOG_MEDIA_POPUP_CLASS = `${DIALOG_POPUP_BASE_CLASS} max-h-[92vh] w-auto max-w-[92vw] overflow-visible rounded-none border border-transparent bg-transparent p-0 shadow-none`; |