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.
33 lines
855 B
TypeScript
33 lines
855 B
TypeScript
export type PinnedTabTarget =
|
|
| { kind: "draft" }
|
|
| { kind: "terminal" }
|
|
| { kind: "browser" }
|
|
| { kind: "profile"; profileId: string };
|
|
|
|
export function pinnedTargetKey(target: PinnedTabTarget): string {
|
|
if (target.kind === "profile") {
|
|
return `profile:${target.profileId}`;
|
|
}
|
|
return target.kind;
|
|
}
|
|
|
|
export function isTargetPinned(
|
|
pinned: readonly PinnedTabTarget[],
|
|
target: PinnedTabTarget,
|
|
): boolean {
|
|
const key = pinnedTargetKey(target);
|
|
return pinned.some((entry) => pinnedTargetKey(entry) === key);
|
|
}
|
|
|
|
export function togglePinnedTarget(
|
|
pinned: readonly PinnedTabTarget[],
|
|
target: PinnedTabTarget,
|
|
): PinnedTabTarget[] {
|
|
const key = pinnedTargetKey(target);
|
|
const next = pinned.filter((entry) => pinnedTargetKey(entry) !== key);
|
|
if (next.length === pinned.length) {
|
|
next.push(target);
|
|
}
|
|
return next;
|
|
}
|