name: zen-folders description: Declarative pinned-tab folder management for Zen browser (Twilight.app). Use this skill when the user wants to manage, reorganize, or inspect tab folders in their Zen browser session via a YAML config file.
What I do
Manage pinned tab folders in Zen browser declaratively. A YAML config file (home/george/zen-folders.yaml) is the source of truth for folder structure, tab assignments, and ordering. The zen-folders CLI reconciles the browser session to match the config.
When to use me
Use this when the user wants to:
- •Add, remove, or reorder tab folders
- •Move tabs between folders or change folder membership
- •Inspect current folder/tab state
- •Bootstrap a new YAML config from the current session
- •Debug folder/session structural issues
Background
Zen is a Firefox fork installed at /Applications/Twilight.app. It stores session data in a Mozilla LZ4-compressed JSON file (zen-sessions.jsonlz4). Folders require entries in two arrays:
- •
groups-- Firefox creates nativetab-groupDOM elements - •
folders-- Zen upgrades those DOM nodes intozen-folderelements
Both must have matching entries for folders to render. Each folder also needs a hidden empty placeholder tab with zenIsEmpty: true.
Zen must be closed when making write changes -- it overwrites the session from DOM state on quit.
Key design decisions
- •List order IS render order -- folder order in YAML =
prevSiblingInfochain; tab order within a folder = position in sessiontabsarray - •Workspace referenced by name (e.g.
"Work"), resolved to UUID at runtime via thespacesarray - •Tab matching by URL substring (case-insensitive) -- use domain names or unique URL fragments as patterns
- •No new tab creation from YAML -- only controls folder structure, ordering, and assignment of existing pinned tabs
CLI location
~/.local/bin/zen-folders
Source: home/george/bin/zen-folders (deployed via home-manager home.file)
Config file
home/george/zen-folders.yaml
Default location: ~/.config/nixcfg/home/george/zen-folders.yaml
YAML format
Work:
Infrastructure:
Fly.io: fly.io
Render: dashboard.render.com
Email:
Resend: resend.com
SendGrid: sendgrid.com
Top-level key is the workspace name. Under it, each key is a folder name. Under each folder, keys are tab titles and values are URL match patterns.
URL patterns: Use domain names or unique URL fragments. Avoid short patterns that could match unintended URLs (e.g. x.com matches dropbox.com; use //x.com instead).
Session file
~/Library/Application Support/zen/Profiles/ecrjha3i.Default (twilight)/zen-sessions.jsonlz4
Commands
Read-only (safe while Zen is running)
# List all folders in order with tab counts zen-folders list zen-folders list -v # also show tab URLs # List all pinned tabs grouped by folder zen-folders tabs # Generate YAML from current session (bootstrap) zen-folders dump zen-folders dump -o zen-folders.yaml # write to file # Show what changes would be made (dry run) zen-folders diff zen-folders diff -c /path/to/custom.yaml
Write commands (Zen must be closed)
# Reconcile session with YAML config zen-folders apply zen-folders apply -y # skip confirmation prompt zen-folders apply -c /path/to/custom.yaml
Backups are created automatically before any write.
Structural check
zen-folders check # verify groups/folders/tabs consistency
Global options
-p, --profile PROFILE # Zen profile dir (default: ecrjha3i.Default (twilight)) -w, --workspace NAME # Workspace name (default: Work)
Workflow for reorganizing folders
- •Inspect current state:
zen-folders list -vorzen-folders tabs - •Edit
home/george/zen-folders.yaml-- add/remove/reorder folders and tabs - •Preview changes:
zen-folders diff - •Close Zen browser
- •Apply:
zen-folders apply - •Open Zen and verify
Workflow for bootstrapping from scratch
- •Set up folders manually in Zen (or they already exist)
- •Close Zen
- •Run
zen-folders dump -o home/george/zen-folders.yaml - •Edit the generated YAML to clean up URLs to short patterns and add titles
- •Verify:
zen-folders diffshould show no changes
Troubleshooting
- •Folders don't appear: Check that both
groupsandfoldersarrays have matching entries (zen-folders check) - •Zen overwrites changes: Always close Zen before running
apply - •Tab not matching: Patterns are case-insensitive URL substrings; use
zen-folders tabsto see exact URLs. Avoid patterns that are substrings of other URLs. - •URL pattern matches multiple tabs: The first match is used and a warning is shown. Make patterns more specific.
- •Process detection: The CLI inspects running processes and matches Zen executable paths (Twilight/Zen app bundles)
Technical details for modifying the script
Source: home/george/bin/zen-folders. Key internals:
- •Session I/O:
read_session()/write_session()handle Mozilla LZ4 format (8-bytemozLz40\0magic + 4-byte LE uncompressed size + lz4 block) - •Workspace resolution:
resolve_workspace()maps names like"Work"to UUIDs via thespacesarray - •Reconciliation engine:
compute_plan()diffs session vs config;apply_plan()mutates session - •Folder creation requires three things: a
groups[]entry, afolders[]entry, and an empty placeholder tab - •Tab assignment: Set the tab's
groupIdfield to the folder'sid - •Ordering:
prevSiblingInfochain for folders; position intabsarray for tabs within a folder - •Dependencies:
python3Packages.lz4+python3Packages.pyyaml(provided via nix-shell shebang)