agentsclimarketplace

Arc to zen migration

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

A Claude Code skill that migrates Arc browser spaces into Zen Browser, automatically, from the files. Folders, pins, and favorites carried over with nesting preserved.

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.

One thing 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.

What its author says it does

Copied from the file, not written here

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.

SKILL.md

5.7 KB, 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 foundbrew 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.

Keep looking

Skills are one crate of 328,083. 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.