Skip to content

Commit de1e42d

Browse files
committed
Merge branch 'opencode-mirror' into fork/local
2 parents 3d971ee + 5586f96 commit de1e42d

77 files changed

Lines changed: 554 additions & 235 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

packages/app/e2e/regression/prompt-thinking-level.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ test("shows the V2 thinking level control while relevant", async ({ page }) => {
5656
await page.goto(`/${base64Encode(directory)}/session/${sessionID}`)
5757
const composer = page.locator('[data-component="prompt-input-v2"]')
5858
const input = composer.locator('[data-component="prompt-input"]')
59-
const control = composer.locator('button[title="Choose model variant"]')
59+
const control = composer.getByRole("button", { name: "Choose model variant" })
6060
await expectAppVisible(composer)
6161

6262
await idleComposer(page)

packages/app/src/components/prompt-input-v2.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import {
3636
export type PromptInputV2ComposerProps = {
3737
class?: string
3838
controller: PromptInputV2ComposerController
39+
borderUnderlay?: boolean
3940
edit?: PromptInputProps["edit"]
4041
onEditLoaded?: PromptInputProps["onEditLoaded"]
4142
}
@@ -57,7 +58,10 @@ export function PromptInputV2Composer(props: PromptInputV2ComposerProps) {
5758
<div class="flex flex-col gap-3">
5859
<PromptInputV2
5960
controller={props.controller}
61+
borderUnderlay={props.borderUnderlay}
6062
class={props.class}
63+
attachKeybind={command.keybindParts("file.attach")}
64+
attachShortcut={command.keybind("file.attach")}
6165
modelControl={
6266
<PromptInputV2ModelControl
6367
loading={props.controller.model.loading}
@@ -449,12 +453,14 @@ export function usePromptInputV2Controller(props: PromptInputV2ControllerProps):
449453
options: () => props.controls.agents.options.map((name) => ({ id: name, label: name })),
450454
current: () => props.controls.agents.current,
451455
onSelect: props.controls.agents.select,
456+
keybind: () => command.keybindParts("agent.cycle"),
452457
}
453458
: undefined,
454459
variant: {
455460
options: () => variants().map((value) => ({ id: value, label: value })),
456461
current: () => props.controls.model.selection.variant.current() ?? "default",
457462
onSelect: (value) => props.controls.model.selection.variant.set(value === "default" ? undefined : value),
463+
keybind: () => command.keybindParts("model.variant.cycle"),
458464
},
459465
submit: {
460466
stopping,

packages/app/src/components/prompt-input.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1460,10 +1460,10 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
14601460
t={(key) => language.t(key as Parameters<typeof language.t>[0])}
14611461
/>
14621462
<DockShellForm
1463+
data-dock-border-underlay="legacy"
14631464
onSubmit={handleSubmit}
14641465
classList={{
14651466
"group/prompt-input": true,
1466-
"focus-within:shadow-xs-border": true,
14671467
"border-icon-info-active border-dashed": store.draggingType !== null,
14681468
[props.class ?? ""]: !!props.class,
14691469
}}

packages/app/src/components/prompt-workspace-selector.tsx

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -93,24 +93,36 @@ export function PromptWorkspaceSelector(props: {
9393
</MenuV2.Content>
9494
</MenuV2.Portal>
9595
</MenuV2>
96-
<Show when={props.branch}>
97-
{(branch) => (
98-
<>
99-
<span class="hidden select-none opacity-50 sm:inline mx-1">/</span>
100-
<TooltipV2
101-
placement="top"
102-
value={branch()}
103-
class="min-w-0 max-w-[220px]"
104-
contentClass="max-w-[calc(100vw-32px)] break-all"
105-
>
106-
<div class="flex h-7 min-w-0 max-w-[220px] items-center gap-1.5 px-2 text-[13px] font-[440] leading-5 tracking-[-0.04px]">
107-
<Icon name="branch" size="small" class="shrink-0 text-v2-icon-icon-muted" />
108-
<span class="min-w-0 truncate">{branch()}</span>
109-
</div>
110-
</TooltipV2>
111-
</>
112-
)}
113-
</Show>
96+
<PromptGitStatus branch={props.branch} />
11497
</>
11598
)
11699
}
100+
101+
export function PromptGitStatus(props: { branch?: string; noGit?: boolean }) {
102+
const language = useLanguage()
103+
const label = () => {
104+
if (props.noGit) return language.t("session.new.git.none")
105+
return props.branch
106+
}
107+
108+
return (
109+
<Show when={label()}>
110+
{(value) => (
111+
<>
112+
<span class="hidden select-none opacity-50 sm:inline mx-1">/</span>
113+
<TooltipV2
114+
placement="top"
115+
value={value()}
116+
class="min-w-0 max-w-[220px]"
117+
contentClass="max-w-[calc(100vw-32px)] break-all"
118+
>
119+
<div class="flex h-7 min-w-0 max-w-[220px] items-center gap-1.5 px-2 text-[13px] font-[440] leading-5 tracking-[-0.04px]">
120+
<Icon name="branch" size="small" class="shrink-0 text-v2-icon-icon-muted" />
121+
<span class="min-w-0 truncate">{value()}</span>
122+
</div>
123+
</TooltipV2>
124+
</>
125+
)}
126+
</Show>
127+
)
128+
}

packages/app/src/components/titlebar.tsx

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export function useTitlebarRightMount() {
6767
return mount
6868
}
6969

70-
export function Titlebar(props: { update?: TitlebarUpdate }) {
70+
export function Titlebar(props: { update?: TitlebarUpdate; debugTools?: { visible: boolean; toggle: () => void } }) {
7171
const layout = useLayout()
7272
const platform = usePlatform()
7373
const command = useCommand()
@@ -462,7 +462,7 @@ export function Titlebar(props: { update?: TitlebarUpdate }) {
462462
"md:pl-4": !mac(),
463463
}}
464464
>
465-
<ChannelIndicator />
465+
<ChannelIndicator debugTools={props.debugTools} />
466466
<Show when={windows() || linux()}>
467467
<WindowsAppMenu command={command} platform={platform} variant="v2" />
468468
</Show>
@@ -660,9 +660,9 @@ export function Titlebar(props: { update?: TitlebarUpdate }) {
660660
</div>
661661
</Show>
662662
<div id="opencode-titlebar-left" class="flex items-center gap-3 min-w-0 px-2" />
663-
<ChannelIndicator />
664663
</div>
665664
</div>
665+
<ChannelIndicator debugTools={props.debugTools} />
666666
</div>
667667
</div>
668668

@@ -747,12 +747,27 @@ function TitlebarUpdateIconButton(props: { state: TitlebarUpdatePillState }) {
747747
)
748748
}
749749

750-
function ChannelIndicator() {
750+
function ChannelIndicator(props: { debugTools?: { visible: boolean; toggle: () => void } }) {
751+
const channel = import.meta.env.VITE_OPENCODE_CHANNEL
752+
if (channel === "dev" && props.debugTools) {
753+
return (
754+
<button
755+
type="button"
756+
class="bg-icon-interactive-base text-[#FFF] font-medium px-2 rounded-sm uppercase font-mono cursor-pointer"
757+
onClick={props.debugTools.toggle}
758+
aria-label="Toggle debug tools"
759+
aria-pressed={props.debugTools.visible}
760+
>
761+
DEV
762+
</button>
763+
)
764+
}
765+
751766
return (
752767
<>
753-
{["beta", "dev"].includes(import.meta.env.VITE_OPENCODE_CHANNEL) && (
768+
{["beta", "dev"].includes(channel) && (
754769
<div class="bg-icon-interactive-base text-[#FFF] font-medium px-2 rounded-sm uppercase font-mono">
755-
{import.meta.env.VITE_OPENCODE_CHANNEL.toUpperCase()}
770+
{channel.toUpperCase()}
756771
</div>
757772
)}
758773
</>

packages/app/src/i18n/ar.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,7 @@ export const dict = {
613613
"session.new.workspace.triggerLocal": "محلي",
614614
"session.new.workspace.local": "المستودع المحلي",
615615
"session.new.workspace.existing": "مساحة عمل…",
616+
"session.new.git.none": "لا يوجد Git",
616617
"session.new.lastModified": "آخر تعديل",
617618
"session.header.search.placeholder": "بحث {{project}}",
618619
"session.header.searchFiles": "بحث عن الملفات",

packages/app/src/i18n/br.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,7 @@ export const dict = {
619619
"session.new.workspace.triggerLocal": "Local",
620620
"session.new.workspace.local": "Repositório local",
621621
"session.new.workspace.existing": "Espaço de trabalho…",
622+
"session.new.git.none": "Sem Git",
622623
"session.new.lastModified": "Última modificação",
623624
"session.header.search.placeholder": "Buscar {{project}}",
624625
"session.header.searchFiles": "Buscar arquivos",

packages/app/src/i18n/bs.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,7 @@ export const dict = {
675675
"session.new.workspace.triggerLocal": "Lokalno",
676676
"session.new.workspace.local": "Lokalni repozitorij",
677677
"session.new.workspace.existing": "Radni prostor…",
678+
"session.new.git.none": "Nema Gita",
678679
"session.new.lastModified": "Posljednja izmjena",
679680

680681
"session.header.search.placeholder": "Pretraži {{project}}",

packages/app/src/i18n/da.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,7 @@ export const dict = {
670670
"session.new.workspace.triggerLocal": "Lokal",
671671
"session.new.workspace.local": "Lokalt repository",
672672
"session.new.workspace.existing": "Arbejdsområde…",
673+
"session.new.git.none": "Ingen Git",
673674
"session.new.lastModified": "Sidst ændret",
674675

675676
"session.header.search.placeholder": "Søg {{project}}",

packages/app/src/i18n/de.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,7 @@ export const dict = {
628628
"session.new.workspace.triggerLocal": "Lokal",
629629
"session.new.workspace.local": "Lokales Repository",
630630
"session.new.workspace.existing": "Arbeitsbereich…",
631+
"session.new.git.none": "Kein Git",
631632
"session.new.lastModified": "Zuletzt geändert",
632633
"session.header.search.placeholder": "{{project}} durchsuchen",
633634
"session.header.searchFiles": "Dateien suchen",

0 commit comments

Comments
 (0)