Add pinnable new-tab targets to the tab row and sidebar

Any new-tab target (new agent, terminal, browser, or a terminal profile)
can be pinned as a quick-launch button. Pins are global client app state
(persisted), not daemon config, so the same set shows on every workspace;
profile pins resolve per host and are dropped where that profile is absent.

The sidebar mirror launches via a navigate-then-launch intent store rather
than calling the create handlers directly: terminal creation only works in
the mounted/focused workspace, so the sidebar requests the launch and the
workspace screen consumes it on focus.
This commit is contained in:
Mohamed Boudra
2026-06-15 14:09:29 +07:00
parent 42969e40d5
commit 713a042dc5
22 changed files with 835 additions and 65 deletions
+25
View File
@@ -0,0 +1,25 @@
import AsyncStorage from "@react-native-async-storage/async-storage";
import { create } from "zustand";
import { createJSONStorage, persist } from "zustand/middleware";
import { isTargetPinned, togglePinnedTarget, type PinnedTabTarget } from "@/workspace-pins/target";
interface PinnedTargetsState {
pinned: PinnedTabTarget[];
toggle: (target: PinnedTabTarget) => void;
isPinned: (target: PinnedTabTarget) => boolean;
}
export const usePinnedTargetsStore = create<PinnedTargetsState>()(
persist(
(set, get) => ({
pinned: [],
toggle: (target) => set((state) => ({ pinned: togglePinnedTarget(state.pinned, target) })),
isPinned: (target) => isTargetPinned(get().pinned, target),
}),
{
name: "pinned-tab-targets",
storage: createJSONStorage(() => AsyncStorage),
partialize: (state) => ({ pinned: state.pinned }),
},
),
);