diff --git a/packages/app/e2e/workspace-pins.spec.ts b/packages/app/e2e/workspace-pins.spec.ts
index 1b94daf6e..aafac4e0b 100644
--- a/packages/app/e2e/workspace-pins.spec.ts
+++ b/packages/app/e2e/workspace-pins.spec.ts
@@ -5,6 +5,7 @@ import { togglePinFromMenu, tabRowPin } from "./helpers/pins";
import { expectTerminalTabOpen } from "./helpers/workspace-tabs";
import type { PinnedTabTarget } from "../src/workspace-pins/target";
+const DRAFT_TARGET: PinnedTabTarget = { kind: "draft" };
const TERMINAL_TARGET: PinnedTabTarget = { kind: "terminal" };
let workspace: SeededWorkspace;
@@ -23,13 +24,13 @@ test.describe("Pinned tab targets", () => {
}) => {
await gotoWorkspace(page, workspace.workspaceId);
- await expect(tabRowPin(page, TERMINAL_TARGET)).toHaveCount(0);
+ await expect(tabRowPin(page, DRAFT_TARGET)).toHaveCount(0);
- await togglePinFromMenu(page, TERMINAL_TARGET);
- await expect(tabRowPin(page, TERMINAL_TARGET)).toBeVisible({ timeout: 10_000 });
+ await togglePinFromMenu(page, DRAFT_TARGET);
+ await expect(tabRowPin(page, DRAFT_TARGET)).toBeVisible({ timeout: 10_000 });
- await togglePinFromMenu(page, TERMINAL_TARGET);
- await expect(tabRowPin(page, TERMINAL_TARGET)).toHaveCount(0, { timeout: 10_000 });
+ await togglePinFromMenu(page, DRAFT_TARGET);
+ await expect(tabRowPin(page, DRAFT_TARGET)).toHaveCount(0, { timeout: 10_000 });
});
test("clicking the pinned quick-launch button in the tab row opens a terminal tab", async ({
@@ -38,7 +39,7 @@ test.describe("Pinned tab targets", () => {
test.setTimeout(45_000);
await gotoWorkspace(page, workspace.workspaceId);
- await togglePinFromMenu(page, TERMINAL_TARGET);
+ await expect(tabRowPin(page, TERMINAL_TARGET)).toBeVisible({ timeout: 10_000 });
await tabRowPin(page, TERMINAL_TARGET).click();
await expectTerminalTabOpen(page);
diff --git a/packages/app/src/screens/workspace/workspace-desktop-tabs-row.tsx b/packages/app/src/screens/workspace/workspace-desktop-tabs-row.tsx
index 2c00248cd..ffce77c0f 100644
--- a/packages/app/src/screens/workspace/workspace-desktop-tabs-row.tsx
+++ b/packages/app/src/screens/workspace/workspace-desktop-tabs-row.tsx
@@ -171,6 +171,44 @@ function PinnableProfileMenuItem({ profile, disabled, onLaunch }: PinnableProfil
interface WorkspaceInlineAddTabButtonProps {
shortcutKeys: ShortcutKey[][] | null;
+ onCreateAgentTab: () => void;
+ onLayout: (event: LayoutChangeEvent) => void;
+}
+
+function WorkspaceInlineAddTabButton({
+ shortcutKeys,
+ onCreateAgentTab,
+ onLayout,
+}: WorkspaceInlineAddTabButtonProps) {
+ const { t } = useTranslation();
+ const tooltipText = t("workspace.tabs.actions.newAgent");
+
+ return (
+
+
+
+
+
+
+
+ {tooltipText}
+ {shortcutKeys ? (
+
+ ) : null}
+
+
+
+
+ );
+}
+
+interface WorkspaceTabRowExtrasProps {
onCreateAgentTab: () => void;
onCreateTerminal: () => void;
onCreateBrowser: () => void;
@@ -179,11 +217,9 @@ interface WorkspaceInlineAddTabButtonProps {
normalizedServerId: string;
showCreateBrowserTab: boolean;
terminalDisabled: boolean;
- onLayout: (event: LayoutChangeEvent) => void;
}
-function WorkspaceInlineAddTabButton({
- shortcutKeys,
+function WorkspaceTabRowExtras({
onCreateAgentTab,
onCreateTerminal,
onCreateBrowser,
@@ -192,8 +228,7 @@ function WorkspaceInlineAddTabButton({
normalizedServerId,
showCreateBrowserTab,
terminalDisabled,
- onLayout,
-}: WorkspaceInlineAddTabButtonProps) {
+}: WorkspaceTabRowExtrasProps) {
const { t } = useTranslation();
const { config } = useDaemonConfig(normalizedServerId);
const profiles = useMemo(
@@ -220,30 +255,8 @@ function WorkspaceInlineAddTabButton({
const launchers = usePinnedLaunchers({ serverId: normalizedServerId, onLaunch });
- const tooltipText = t("workspace.tabs.actions.newAgent");
-
return (
-
-
-
-
-
-
-
- {tooltipText}
- {shortcutKeys ? (
-
- ) : null}
-
-
-
-
+ <>
@@ -251,7 +264,7 @@ function WorkspaceInlineAddTabButton({
testID="workspace-new-tab-menu-trigger"
accessibilityRole="button"
accessibilityLabel={t("workspace.tabs.actions.moreActions")}
- style={inlineAddActionButtonStyle}
+ style={newTabActionButtonStyle}
>
@@ -301,7 +314,8 @@ function WorkspaceInlineAddTabButton({
-
+
+ >
);
}
@@ -975,6 +989,12 @@ export function WorkspaceDesktopTabsRow({
/>
+
+
+
-
-
{showPaneSplitActions ? (
<>
({
alignItems: "center",
},
pinButton: {
- width: 28,
- height: 28,
+ width: 22,
+ height: 22,
borderRadius: theme.borderRadius.md,
alignItems: "center",
justifyContent: "center",
diff --git a/packages/app/src/workspace-pins/store.ts b/packages/app/src/workspace-pins/store.ts
index ef986d9af..524264b43 100644
--- a/packages/app/src/workspace-pins/store.ts
+++ b/packages/app/src/workspace-pins/store.ts
@@ -9,6 +9,18 @@ interface PinnedTargetsState {
isPinned: (target: PinnedTabTarget) => boolean;
}
+const DEFAULT_PINNED_TARGETS: PinnedTabTarget[] = [{ kind: "terminal" }, { kind: "browser" }];
+
+function applyDefaultPinnedTargets(pinned: PinnedTabTarget[]): PinnedTabTarget[] {
+ const next = [...DEFAULT_PINNED_TARGETS];
+ for (const target of pinned) {
+ if (!isTargetPinned(next, target)) {
+ next.push(target);
+ }
+ }
+ return next;
+}
+
export const usePinnedTargetsStore = create()(
persist(
(set, get) => ({
@@ -18,8 +30,16 @@ export const usePinnedTargetsStore = create()(
}),
{
name: "pinned-tab-targets",
+ version: 1,
storage: createJSONStorage(() => AsyncStorage),
partialize: (state) => ({ pinned: state.pinned }),
+ migrate: (persistedState, version) => {
+ if (version === 0) {
+ const pinned = (persistedState as { pinned?: PinnedTabTarget[] } | null)?.pinned ?? [];
+ return { pinned: applyDefaultPinnedTargets(pinned) };
+ }
+ return persistedState as PinnedTargetsState;
+ },
},
),
);