scasella/tabpilot/add-feature-skill
Claude Code and agent skill by scasella/tabpilot
- community
Checking that the SKILL.md file is still in the repository.
Guide for adding new features to TabPilot. Covers architecture, extension points, patterns, and build process.
Install
npx vskill@latest install scasella/tabpilot/add-feature-skillSKILL.md
Overview
TabPilot is a macOS menu bar app that serves as a Safari tab command center -- it polls Safari tabs via AppleScript, tracks tab age with JSON persistence, groups tabs by domain, and supports AI-powered semantic clustering via the Codex WebSocket protocol.
Architecture
TabPilot is a single-file SwiftUI menu bar app (TabPilot.swift, ~1645 lines). It uses the @main struct TabPilotApp with a MenuBarExtra(.window) scene. Two @Observable classes own all mutable state:
- `SafariScanner` -- polls Safari every 5 seconds via AppleScript, maintains the live tab list, computes domain groups and duplicate detection, and persists tab history to
~/.tabpilot/tab_history.json. - `TabClusterer` -- connects to the Codex app-server over WebSocket (JSON-RPC 2.0), sends tab data for AI-powered semantic clustering, and supports natural-language tab queries.
Both are held as @State properties on the App struct and passed into ContentView.
Key Types
| Type | Kind | Description | |
|---|---|---|---|
TPTheme | enum | Static color constants for the dark UI theme | |
RawWebSocket | class | NWConnection-based WebSocket client (shared pattern across apps) | |
SafariTab | struct | Identifiable tab with url, title, windowIndex, tabIndex, domain helpers | |
AgeCategory | enum | Four tiers: .fresh, .warm, .cooling, .stale with color and label | |
TabCluster | struct | AI-generated cluster with name, description, and tab list | |
FilterMode | enum | CaseIterable filter options (all, duplicates, fresh, warm, cooling, stale) | |
ViewMode | enum | CaseIterable view modes (domains, clusters) | |
TabHistory / TabHistoryStore | struct/enum | Codable persistence of first-seen timestamps per URL | |
SafariScanner | @Observable class | Safari polling, tab list, domain grouping, history tracking | |
ClusterState | enum | FSM for clustering: idle, connecting, clustering, done, error | |
TabClusterer | @Observable class | Codex AI integration for semantic clustering and NL queries | |
TabCountBadge | View | Displays tab count in a pill badge | |
FilterChips | View | Horizontal row of filter mode toggle buttons | |
AgeBadge | View | Colored dot + label for tab age category | |
DomainIcon | View | Favicon-style first-letter icon for a domain | |
TabRowView | View | Single tab row with title, domain, age, and action buttons | |
DomainGroupView | View | Collapsible section grouping tabs by domain | |
ClusterGroupView | View | Collapsible section grouping tabs by AI cluster | |
ContentView | View | Root view with filter chips, view mode toggle, tab list, and cluster UI |
How to Add a Feature
- Define any new model types at the top of
TabPilot.swiftin the// MARK: - Modelssection. Follow the existing pattern: Identifiable structs, CaseIterable enums.
- If the feature needs new state, add properties to the appropriate
@Observableclass:
- Tab data, scanning, or Safari interaction -->
SafariScanner - AI/Codex integration or clustering -->
TabClusterer - If neither fits, consider creating a new
@Observableclass and adding it as@StateinTabPilotApp.
- If adding a new filter, add a case to
FilterModeand update the filtering logic inContentView(thefilteredTabscomputed property).
- If adding a new view mode, add a case to
ViewModeand add a corresponding branch inContentView's body that renders the new grouping.
- If adding a new view, create a new
struct MyView: Viewin the// MARK: - Viewssection. UseTPThemecolors for all styling.
- If adding a new Codex AI interaction, follow the
TabClustererpattern:
- Connect via
RawWebSocketto127.0.0.1:4663 - Send
initializeJSON-RPC request, thenthread/start, thenturn/startwith your prompt - Handle streaming deltas via
item/agentMessage/deltanotifications - Parse the accumulated response when the turn completes
- Build and test with
bash build.shthenopen TabPilot.app.
Extension Points
- New FilterMode cases -- add to the
FilterModeenum, implement filtering logic in ContentView - New ViewMode cases -- add to
ViewModeenum, implement grouping/rendering in ContentView - New scanner data -- extend
SafariScanner.scanAllTabs()AppleScript to extract additional tab properties (e.g., favicons, reading progress) - New AI-powered features -- follow the
TabClustererpattern: create a new@Observableclass with its ownClusterState-style FSM, connect to Codex, send prompts, parse streaming responses - New tab actions -- add buttons to
TabRowViewthat call AppleScript commands (close tab, move tab, open URL) - Tab history analytics -- extend
TabHistory/TabHistoryStoreto track additional metrics (visit count, time spent)
Conventions
- Theme: All colors come from
TPThemestatic properties. UseTPTheme.bgfor backgrounds,TPTheme.surfacefor cards,TPTheme.accentfor interactive elements. - WebSocket/JSON-RPC: The
RawWebSocketclass handles raw TCP + WebSocket framing via NWConnection. JSON-RPC 2.0 messages use sequential integer IDs tracked inpendingRequests: [Int: String]. Always sendinitializebeforethread/startbeforeturn/start. - SF Symbols: Used throughout for icons (
safari,arrow.clockwise,doc.on.doc,sparkles,xmark.circle). Keep the icon style consistent. - AppleScript: Safari interaction is done via
NSAppleScript. Scripts queryevery windowandevery tabfor URL and title. Keep scripts minimal for performance. - State machines: Async operations use enum FSMs (e.g.,
ClusterState) to drive UI transitions. The view switches on state to show appropriate content. - Persistence: Tab history is stored as JSON at
~/.tabpilot/tab_history.jsonviaTabHistoryStore.save()/load().
Build & Test
Requires macOS 14.0+ and Xcode command-line tools. The app runs as LSUIElement (no Dock icon). Safari automation requires user approval for AppleScript access.
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingadd-feature-skill/SKILL.md
Popularity
- 7-day trend score
- 0
Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/scasella/tabpilot/add-feature-skill)