diff --git a/.github/actions/setup-bun/action.yml b/.github/actions/setup-bun/action.yml index 6c632f7e07..3f06da5197 100644 --- a/.github/actions/setup-bun/action.yml +++ b/.github/actions/setup-bun/action.yml @@ -31,6 +31,10 @@ runs: bun-version-file: ${{ !steps.bun-url.outputs.url && 'package.json' || '' }} bun-download-url: ${{ steps.bun-url.outputs.url }} + - name: Install setuptools for distutils compatibility + run: python3 -m pip install setuptools || pip install setuptools || true + shell: bash + - name: Install dependencies run: bun install shell: bash diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f7b00516f8..d9eded3f17 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,6 +6,14 @@ on: - dev pull_request: workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +permissions: + contents: read + jobs: unit: name: unit (${{ matrix.settings.name }}) @@ -86,18 +94,3 @@ jobs: path: | packages/app/e2e/test-results packages/app/e2e/playwright-report - - required: - name: test (linux) - runs-on: blacksmith-4vcpu-ubuntu-2404 - needs: - - unit - - e2e - if: always() - steps: - - name: Verify upstream test jobs passed - run: | - echo "unit=${{ needs.unit.result }}" - echo "e2e=${{ needs.e2e.result }}" - test "${{ needs.unit.result }}" = "success" - test "${{ needs.e2e.result }}" = "success" diff --git a/.opencode/.gitignore b/.opencode/.gitignore index 00bfdfda29..03445edaf2 100644 --- a/.opencode/.gitignore +++ b/.opencode/.gitignore @@ -1,3 +1,4 @@ plans/ bun.lock package.json +package-lock.json diff --git a/nix/hashes.json b/nix/hashes.json index d4146be6b7..153f78ac6d 100644 --- a/nix/hashes.json +++ b/nix/hashes.json @@ -1,8 +1,8 @@ { "nodeModules": { - "x86_64-linux": "sha256-duBedS4ZTc1as03OM0KB9mKKU21Cywv4o9GHwQZv6Ts=", - "aarch64-linux": "sha256-juvQfuNBqqzeB/TIY9PuUDqgpsdyI54ImowjQLrNhns=", - "aarch64-darwin": "sha256-kKgcuEN1oJqHJc+sGjcZ4INWvbZczSTDJ8VHIWAquD4=", - "x86_64-darwin": "sha256-hXkFWOL4wi9s8HSrChpqtH4PKSNzbzVgU+0GbAxEUT4=" + "x86_64-linux": "sha256-dhL4YeSi4Lm9yDp919Fx7N2hyLUbZQa2qWoCf/50ce8=", + "aarch64-linux": "sha256-//YxCsrvYlxuvd0MtFFO+pLxjmuemyrvGzSIPxzO+rA=", + "aarch64-darwin": "sha256-c65kSWteQNaBcQUsjbXNqT61vt98JPNYo9yMNvUygCw=", + "x86_64-darwin": "sha256-hlTzEFv3nZHwlDXU65LfMC+NaqYjjyZqagdJ366CNxY=" } } diff --git a/packages/app/e2e/prompt/prompt-slash-terminal.spec.ts b/packages/app/e2e/prompt/prompt-slash-terminal.spec.ts index eefce19dc0..bf9f96b47f 100644 --- a/packages/app/e2e/prompt/prompt-slash-terminal.spec.ts +++ b/packages/app/e2e/prompt/prompt-slash-terminal.spec.ts @@ -9,14 +9,12 @@ test("/terminal toggles the terminal panel", async ({ page, gotoSession }) => { await expect(terminal).not.toBeVisible() - await prompt.click() - await page.keyboard.type("/terminal") + await prompt.fill("/terminal") await expect(page.locator('[data-slash-id="terminal.toggle"]').first()).toBeVisible() await page.keyboard.press("Enter") await expect(terminal).toBeVisible() - await prompt.click() - await page.keyboard.type("/terminal") + await prompt.fill("/terminal") await expect(page.locator('[data-slash-id="terminal.toggle"]').first()).toBeVisible() await page.keyboard.press("Enter") await expect(terminal).not.toBeVisible() diff --git a/packages/app/e2e/selectors.ts b/packages/app/e2e/selectors.ts index 2061a11284..64b7bfe545 100644 --- a/packages/app/e2e/selectors.ts +++ b/packages/app/e2e/selectors.ts @@ -1,5 +1,6 @@ export const promptSelector = '[data-component="prompt-input"]' -export const terminalSelector = '[data-component="terminal"]' +export const terminalPanelSelector = '#terminal-panel[aria-hidden="false"]' +export const terminalSelector = `${terminalPanelSelector} [data-component="terminal"]` export const sessionComposerDockSelector = '[data-component="session-prompt-dock"]' export const questionDockSelector = '[data-component="dock-prompt"][data-kind="question"]' export const permissionDockSelector = '[data-component="dock-prompt"][data-kind="permission"]' diff --git a/packages/app/src/components/session/session-header.tsx b/packages/app/src/components/session/session-header.tsx index 9b4551584c..97f0530e98 100644 --- a/packages/app/src/components/session/session-header.tsx +++ b/packages/app/src/components/session/session-header.tsx @@ -21,6 +21,8 @@ import { useLayout } from "@/context/layout" import { usePlatform } from "@/context/platform" import { useServer } from "@/context/server" import { useSync } from "@/context/sync" +import { useTerminal } from "@/context/terminal" +import { focusTerminalById } from "@/pages/session/helpers" import { decode64 } from "@/utils/base64" import { Persist, persisted } from "@/utils/persist" import { StatusPopover } from "../status-popover" @@ -229,6 +231,7 @@ export function SessionHeader() { const sync = useSync() const platform = usePlatform() const language = useLanguage() + const terminal = useTerminal() const projectDirectory = createMemo(() => decode64(params.dir) ?? "") const project = createMemo(() => { @@ -296,6 +299,16 @@ export function SessionHeader() { ] as const }) + const toggleTerminal = () => { + const next = !view().terminal.opened() + view().terminal.toggle() + if (!next) return + + const id = terminal.active() + if (!id) return + focusTerminalById(id) + } + const [prefs, setPrefs] = persisted(Persist.global("open.app"), createStore({ app: "finder" as OpenApp })) const [menu, setMenu] = createStore({ open: false }) const [openRequest, setOpenRequest] = createStore({ @@ -617,39 +630,39 @@ export function SessionHeader() {
-