raycast-alfred
Included with Lifetime
$97 forever
macOS launcher automation with Raycast extensions (TypeScript/React) and Alfred workflows (AppleScript/Python) for keyboard-driven productivity
devtoolsraycastalfredmacoslauncherautomationproductivityscriptstypescript
What this skill does
# Raycast & Alfred Skill
Master macOS launcher automation with Raycast extensions and Alfred workflows. This skill covers TypeScript-based Raycast development, AppleScript/Python Alfred workflows, keyboard shortcuts, clipboard management, and productivity automation patterns.
## When to Use This Skill
### USE when:
- Building quick access tools for developer workflows
- Automating repetitive macOS tasks
- Creating custom search commands
- Building clipboard history managers
- Implementing text snippet expansion
- Creating project launchers and switchers
- Building API query tools
- Automating application control
- Creating custom keyboard shortcuts
- Building team productivity tools
### DON'T USE when:
- Cross-platform automation needed (use shell scripts)
- Server-side automation (use cron/systemd)
- GUI testing automation (use Playwright/Selenium)
- Windows/Linux environments
- Heavy computation tasks (use proper CLI tools)
## Prerequisites
### Raycast Setup
```bash
# Install Raycast
brew install --cask raycast
# Install Node.js (required for extension development)
brew install node
# Install Raycast CLI
npm install -g @raycast/api
# Create new extension
npx create-raycast-extension --name my-extension
# Development mode
cd my-extension
npm install
npm run dev
# Extension structure
# my-extension/
# ├── package.json
# ├── tsconfig.json
# ├── src/
# │ ├── index.tsx # Main command
# │ └── other-command.tsx # Additional commands
# └── assets/
# └── icon.png # Extension icon
```
### Alfred Setup
```bash
# Install Alfred (Powerpack required for workflows)
brew install --cask alfred
# Alfred workflow locations
# ~/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/
# Create workflow via Alfred Preferences > Workflows > + > Blank Workflow
# Workflow components:
# - Triggers: Keywords, hotkeys, file actions
# - Actions: Scripts, open URL, run NSAppleScript
# - Outputs: Notifications, copy to clipboard, play sound
# Script languages supported:
# - bash, zsh
# - Python (2 or 3)
# - AppleScript / JavaScript for Automation (JXA)
# - Ruby, PHP, Perl
```
### Development Environment
```bash
# For Raycast TypeScript development
npm install -g typescript @types/node
# For Alfred Python workflows
pip install alfred-workflow # (legacy, but useful patterns)
# AppleScript tools
brew install --cask script-debugger # Optional: AppleScript IDE
# Testing tools
brew install jq # JSON parsing
```
## Core Capabilities
### 1. Raycast Script Commands
```bash
#!/bin/bash
# Required parameters:
# @raycast.schemaVersion 1
# @raycast.title Open Project
# @raycast.mode silent
# Optional parameters:
# @raycast.icon 📁
# @raycast.argument1 { "type": "text", "placeholder": "Project name", "optional": false }
# @raycast.packageName Developer Tools
# Documentation:
# @raycast.description Opens a project in VS Code
# @raycast.author Your Name
# @raycast.authorURL https://github.com/yourname
PROJECT="$1"
PROJECT_DIR="$HOME/projects/$PROJECT"
if [ -d "$PROJECT_DIR" ]; then
code "$PROJECT_DIR"
echo "Opened $PROJECT"
else
echo "Project not found: $PROJECT"
exit 1
fi
```
```bash
#!/bin/bash
# @raycast.schemaVersion 1
# @raycast.title Git Status
# @raycast.mode fullOutput
# @raycast.icon 🔀
# @raycast.packageName Git
# @raycast.description Show git status for current directory
# @raycast.author workspace-hub
cd "$(pwd)" || exit 1
if [ -d ".git" ]; then
echo "Branch: $(git branch --show-current)"
echo ""
echo "Status:"
git status --short
echo ""
echo "Recent commits:"
git log --oneline -5
else
echo "Not a git repository"
exit 1
fi
```
```python
#!/usr/bin/env python3
# Required parameters:
# @raycast.schemaVersion 1
# @raycast.title UUID Generator
# @raycast.mode silent
# Optional parameters:
# @raycast.icon 🔑
# @raycast.argument1 { "type": "dropdown", "placeholder": "Format", "data": [{"title": "Standard", "value": "standard"}, {"title": "No dashes", "value": "nodash"}, {"title": "Uppercase", "value": "upper"}] }
# @raycast.packageName Utilities
import uuid
import subprocess
import sys
format_type = sys.argv[1] if len(sys.argv) > 1 else "standard"
new_uuid = str(uuid.uuid4())
if format_type == "nodash":
new_uuid = new_uuid.replace("-", "")
elif format_type == "upper":
new_uuid = new_uuid.upper()
# Copy to clipboard
subprocess.run(["pbcopy"], input=new_uuid.encode(), check=True)
print(f"Copied: {new_uuid}")
```
```bash
#!/bin/bash
# @raycast.schemaVersion 1
# @raycast.title Kill Port
# @raycast.mode compact
# @raycast.icon 🔌
# @raycast.argument1 { "type": "text", "placeholder": "Port number" }
# @raycast.packageName Developer Tools
PORT="$1"
# Find process on port
PID=$(lsof -ti:$PORT 2>/dev/null)
if [ -z "$PID" ]; then
echo "No process on port $PORT"
exit 0
fi
# Kill the process
kill -9 $PID 2>/dev/null
if [ $? -eq 0 ]; then
echo "Killed process $PID on port $PORT"
else
echo "Failed to kill process on port $PORT"
exit 1
fi
```
### 2. Raycast TypeScript Extensions
```tsx
// src/index.tsx
// ABOUTME: Raycast extension main command
// ABOUTME: Project launcher with favorites and recent
import {
ActionPanel,
Action,
List,
Icon,
LocalStorage,
showToast,
Toast,
getPreferenceValues,
} from "@raycast/api";
import { useState, useEffect } from "react";
import { exec } from "child_process";
import { promisify } from "util";
import fs from "fs";
import path from "path";
const execAsync = promisify(exec);
interface Preferences {
projectsDir: string;
editor: string;
}
interface Project {
name: string;
path: string;
lastOpened?: number;
isFavorite?: boolean;
}
export default function Command() {
const [projects, setProjects] = useState<Project[]>([]);
const [isLoading, setIsLoading] = useState(true);
const preferences = getPreferenceValues<Preferences>();
useEffect(() => {
loadProjects();
}, []);
async function loadProjects() {
try {
const projectsDir = preferences.projectsDir.replace("~", process.env.HOME || "");
const dirs = fs.readdirSync(projectsDir, { withFileTypes: true });
// Load favorites and recent from storage
const favoritesJson = await LocalStorage.getItem<string>("favorites");
const recentJson = await LocalStorage.getItem<string>("recent");
const favorites = favoritesJson ? JSON.parse(favoritesJson) : [];
const recent = recentJson ? JSON.parse(recentJson) : {};
const projectList: Project[] = dirs
.filter((dir) => dir.isDirectory() && !dir.name.startsWith("."))
.map((dir) => ({
name: dir.name,
path: path.join(projectsDir, dir.name),
lastOpened: recent[dir.name] || 0,
isFavorite: favorites.includes(dir.name),
}))
.sort((a, b) => {
// Favorites first, then by recent
if (a.isFavorite && !b.isFavorite) return -1;
if (!a.isFavorite && b.isFavorite) return 1;
return (b.lastOpened || 0) - (a.lastOpened || 0);
});
setProjects(projectList);
} catch (error) {
showToast({
style: Toast.Style.Failure,
title: "Failed to load projects",
message: String(error),
});
} finally {
setIsLoading(false);
}
}
async function openProject(project: Project) {
try {
const editor = preferences.editor || "code";
await execAsync(`${editor} "${project.path}"`);
// Update recent
const recentJson = await LocalStorage.getItem<string>("recent");
const recent = recentJson ? JSON.parse(recentJson) : {};
recent[project.name] = Date.now();
await LocalStorage.setItem("recent", JSON.stringify(recent));
showToast({
style: Toast.Style.Success,
title: `Opened ${project.name}`,
});
} catch (error) {
showToast({
style: Toast.Style.Failure,
title: "Failed to open project",Related in devtools
vscode-extensions
IncludedVS Code productivity optimization with essential extensions, settings sync, profiles, keybindings, snippets, and workspace configuration
devtools
cli-productivity
IncludedEssential CLI tools and shell productivity patterns for efficient terminal workflows
devtools
docker
IncludedComplete Docker containerization patterns for development and production workflows
devtools
git-advanced
IncludedAdvanced git workflows including rebase, worktrees, bisect, hooks, and monorepo patterns
devtools
pyproject-toml
IncludedConfigure Python projects with pyproject.toml for modern packaging, tools, and dependency management
devtools
uv-package-manager
IncludedUV for fast Python package management, virtual environments, and project workflows
devtools