I use this script so much, I had to share it. It lets you select a personal or team project that is hosted on Vercel and opens the dashboard page of the selected project.
Open open-vercel-project in Script Kit
/*# Open Vercel project dashboardLets the user select and open the dashboard page of a project hosted on Vercel.*/// Name: Open Vercel project dashboard// Description: Lets the user select and open the dashboard page of a project hosted on Vercel.// Author: Michael Rieger// Twitter: @muesliriegerimport '@johnlindquist/kit';const apiBaseUrl = 'https://api.vercel.com';const dashboardBaseUrl = 'https://vercel.com';// ask user to create an access token for the rest apiconst VERCEL_ACCESS_TOKEN = await env('VERCEL_ACCESS_TOKEN', {panel: md(`## Get a [Vercel API Access Token](https://vercel.com/account/tokens)`),ignoreBlur: true,secret: true,});const user = await fetchUser();// Select whether personal or team projects should be listedconst projectsType = await selectProjectsType();// If team projects were selected list the teams the user is assigned tolet team: Team | undefined | null = null;if (projectsType === 'team') {const teams = await fetchTeams();team = await selectTeam(teams);}// Fetch projects based on previous selectionconst projects = await fetchProjects(team?.id);// let user select project and open in browserconst project = await selectProject(projects);if (!project) exit(-1);await browse(`${dashboardBaseUrl}/${projectsType === 'team' ? team.slug : user.username}/${project.name}`);// -----------------------------------------------------// Helpers// -----------------------------------------------------type VercelApiError = {error?: {code: string;message: string;};};async function selectProjectsType() {return arg<'personal' | 'team'>('Show personal or team projects', [{value: 'personal',name: '[P]ersonal',shortcut: 'p',},{value: 'team',name: '[T]eam',shortcut: 't',},]);}type User = {id: string;email: string;name: string | null;username: string;};type GetUserResponse = { user: User } & VercelApiError;async function fetchUser() {try {const res = await get<GetUserResponse>(`${apiBaseUrl}/v2/user`, {headers: { Authorization: `Bearer ${VERCEL_ACCESS_TOKEN}` },});if (res.status !== 200 || res.data.error) exit();return res.data.user;} catch (e) {exit(-1);}}type Team = { id: string; name: string; slug: string; avatar: string | null };type GetTeamsResponse = { teams?: Team[] } & VercelApiError;async function fetchTeams() {try {const res = await get<GetTeamsResponse>(`${apiBaseUrl}/v2/teams`, {headers: { Authorization: `Bearer ${VERCEL_ACCESS_TOKEN}` },});if (res.status !== 200 || res.data.error) exit();return res.data.teams;} catch (e) {exit(-1);}}async function selectTeam(teams: Team[]) {return await arg<Team>({placeholder: teams.length ? 'Select a team' : 'No teams found',onChoiceFocus: (input, { focused }) => {setPlaceholder(focused.name);},enter: `Select team`,},teams.map((team) => ({value: team,name: team.name,img: team.avatar ? `https://vercel.com/api/www/avatar/${team.avatar}?s=128` : '',})));}type Project = { id: string; name: string; latestDeployments: { alias: string[] }[] };type GetProjectsResponse = { projects?: Project[] } & VercelApiError;async function fetchProjects(teamId?: string | null | undefined) {try {const res = await get<GetProjectsResponse>(`${apiBaseUrl}/v9/projects${teamId ? `?teamId=${teamId}` : ''}`, {headers: { Authorization: `Bearer ${VERCEL_ACCESS_TOKEN}` },});if (res.status !== 200 || res.data.error) exit();return res.data.projects;} catch (e) {exit(-1);}}async function selectProject(projects: Project[]) {return await arg<Project>({placeholder: projects.length ? 'Select a project' : 'No projects found',onChoiceFocus: (input, { focused }) => {setPlaceholder(focused.name);},enter: `Open project in dashboard`,},projects.map((project) => ({value: project,name: project.name,})));}