agentsclimarketplace

Arc to zen migration

Skill shub-rajput/arc-to-zen-migration

Use when migrating Arc browser spaces/workspaces into Zen Browser, or bulk-creating Zen workspaces, folders, essentials, or pinned tabs by editing the session store. Covers reading/writing Zen's mozlz4 session file and its folder/group/space schema.From its SKILL.md

Install
npx -y skills add shub-rajput/arc-to-zen-migration

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
  • runs commandsInstructs the agent to run 6 commands, including `python3 scripts/migrate.py --list` and 5 more.

SKILL.md

5.7 KB, ~1.4k tokens by cl100k_base, as published. Nobody here has run it

Arc → Zen Migration

Overview

Zen has no Arc importer. But Zen (Firefox-based) keeps its whole tab/folder/workspace state in one compressed file you can script against, so Arc spaces can be rebuilt in bulk — folders become folders, not flat pins.

Read side (Arc): ~/Library/Application Support/Arc/StorableSidebar.json — plain JSON holding every space, folder, and pinned tab. No manual pasting needed. Write side (Zen): <profile>/zen-sessions.jsonlz4 — Mozilla-lz4 (mozLz40\0) compressed JSON.

Tools:

  • scripts/arc_extract.py — reads Arc's sidebar, returns each space as a nested tree.
  • scripts/zen_session.py — read/write Zen's mozlz4 session + folder/tab/essential builders.
  • scripts/migrate.py — end-to-end: Arc space → Zen workspace (preserves nested folders).
  • scripts/migrate_example.py — manual fill-in template (when there's no Arc file, e.g. user pastes URLs).

When to Use

  • "Migrate my Arc workspaces/spaces to Zen"
  • "Bulk add folders / pinned tabs / essentials to Zen"
  • Recreating Arc's folder structure inside a Zen workspace

Not for: bookmarks (use Arc export HTML → Zen bookmark import) or passwords (use a password manager / keychain export).

The Iron Rule

Zen MUST be fully quit (Cmd+Q) before writing. It rewrites the session on exit and will clobber your changes otherwise. Always backup() first — a wrong schema corrupts the session; the .bak restores instantly.

Workflow (automatic — Arc installed)

  1. Quit Zen (Cmd+Q) — non-negotiable (see Iron Rule).
  2. Preview: python3 scripts/migrate.py --list prints Arc spaces ↔ Zen workspaces.
  3. Migrate everything from zero: python3 scripts/migrate.py --all --favorites — creates a Zen workspace per Arc space (with Arc's emoji icon), imports folders + pins, and adds Arc's global Favorites as global essentials.
  4. Or one space: python3 scripts/migrate.py "Home" --favorites (creates the workspace if missing; --zen "Name" maps to a differently-named one; --essentials N promotes the first N top-level pins to essentials).
  5. Reopen Zen, verify. Re-runnable — clear_workspace wipes the target first. Restore the .bak if wrong.

Mapping Arc → Zen: space list → folder (nesting preserved) · space top-level tab → regular pin · global Favorites (topApps) → global essentials.

Workflow (manual — no Arc file, user pastes URLs)

Use migrate_example.py: fill ESSENTIALS/PINS/FOLDERS, quit Zen, run. Screenshots of the Arc sidebar are enough to fill it.

If Zen's schema drifted (script misbehaves): make ONE folder with 2 tabs by hand in Zen, quit, zen_session.py <profile> --dump, compare the live folders[]/groups[]/tabs[] shapes, update the builders.

Schema (Zen 1.20.x / Firefox 151)

A folder = two synced records sharing one id, plus member tabs:

WhereKey fields
folders[]id, name, workspaceId, collapsed, parentId:null, emptyTabIds:[], userIcon
groups[]id (same), name, color:"zen-workspace-color", collapsed
tabs[] (member)groupId:<folder id>, zenWorkspace:<space uuid>, pinned:true, zenEssential:false
  • Essential: zenEssential:true. Scoped by CONTAINER (userContextId), not zenWorkspace — this is the #1 gotcha. With zen.workspaces.separate-essentials=true (Zen default), an essential shows only in workspaces whose containerTabId matches its userContextId; userContextId:0 = the default container = the first/Home workspace. To make essentials global (Arc-style, same in every space), set zen.workspaces.separate-essentials=false (via user.js) and use userContextId:0 / zenWorkspace:null. For a per-workspace essential, set userContextId to that workspace's containerTabId.
  • Plain pin: zenEssential:false, zenWorkspace:<uuid>, no groupId. Scoped by zenWorkspace (works with userContextId:0).
  • Workspace lives in spaces[]: {uuid, name, icon(emoji), containerTabId, position, theme}. ensure_workspace() creates one if absent.
  • Ordering = tab array order. tab.index is the active history-entry pointer (set to 1), NOT position.
  • IDs are <epoch_ms>-<counter>. Tabs need only a minimal entries:[{url,title,triggeringPrincipal_base64:"{\"3\":{}}"}]; Firefox fills the rest on load.
  • Skip arc://* URLs — they don't resolve in Zen.

Library Quickref

from zen_session import ZenSession, find_profiles
s = ZenSession(find_profiles()[0])
s.backup()
home = s.workspace_by_name("Home")
s.clear_folders(workspace=home)                 # idempotent re-runs
s.add_essential("https://discord.com/")         # global top icon
s.add_tab("https://news.com/", workspace=home)  # plain pin
fid = s.add_folder("Finance", home)
s.add_tab("https://sheet/", workspace=home, folder_id=fid)
s.save()                                         # Zen must be quit

Common Mistakes

  • Writing while Zen runs → changes vanish on quit. Quit first.
  • Folder in only one array → ghost/empty folder. Always write BOTH folders[] and groups[] (the library does).
  • Tab missing zenWorkspace → tab lands in the wrong/no space. Set it (essentials use null).
  • liblz4 not found → brew install lz4 (mac) / apt install liblz4-1 (linux); fix the path list in zen_session.py if needed.
  • No backup → re-run with backup(); keep the .bak until verified.

What ships with it: 7 files

28.6 KB alongside SKILL.md, 4 of them executable

scripts/

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.