Worktree file sync

In GIT mode, every Friday thread runs in its own git worktree on a friday/thread/<id> branch. A fresh worktree only contains files that git knows about, so anything untracked stays behind: .env, node_modules, .venv, build caches, IDE state. Worktree file sync is the opt-in mechanism that copies or symlinks specific paths from your main checkout into each new worker worktree, so threads can actually run your project.

What gets synced by default

Nothing. The list starts empty and you add the entries you need per project. Friday does not guess at .env or node_modules; you tell it exactly what to bring along.

How to configure

Worktree file sync is a setting under worktree_sync (note the key is worktree_sync, not worktree_file_sync despite the page name). It is scoped per project, so different repos can sync different things.

The recommended way is interactive:

  1. Inside Friday, run /settings.
  2. Pick Worktree File Sync.
  3. Add an entry: a path relative to the repo root and a strategy.

Each entry has two fields:

  • path: relative to the source repo root. Absolute paths and .. segments are rejected.
  • strategy: either copy or symlink.

You can also edit ~/.friday/.user_preferences.yaml directly. Sync entries live under working_directory_mappings.<absolute-path>.worktree_sync:

working_directory_mappings:
  /Users/you/code/my-app:
    worktree_sync:
      - path: .env
        strategy: copy
      - path: node_modules
        strategy: symlink
      - path: .venv
        strategy: symlink
      - path: .vscode/settings.json
        strategy: copy

Copy versus symlink

The two strategies trade off isolation against shared state.

  • Copy: the worktree gets its own snapshot of the file or directory. Writes in the worktree do not affect the source. Good for .env (you usually do not want a thread mutating shared secrets) and small read-only configs. Latency at thread spawn scales with the size of what you copy.
  • Symlink: the worktree's path links to the original. The thread reads and writes the same bytes as your main checkout. Good for caches like node_modules and .venv where copying gigabytes per thread is wasteful. Be aware that any write through the symlink touches the original, and concurrent workers writing through the same symlink can collide.

Common patterns

  • .env as copy. Threads need the env vars but should not share live writes back to your working copy.
  • node_modules as symlink. Avoids re-installing dependencies in every thread. Safe as long as threads are not running npm install concurrently.
  • .venv as symlink. Same reasoning as node_modules.
  • .vscode/settings.json as copy. IDE config travels with the worktree without coupling.
  • Build output directories. Usually skip. Symlinking a build directory while two threads run concurrent builds will collide; copying it can be slow. Prefer rebuilding inside the thread.

Failure modes

  • Validation failure. If a path resolves outside the source repo (absolute path, .. traversal), Friday rejects the entry.
  • Sync error. If a sync operation fails (missing source, permission denied, broken symlink target), Friday logs the failure and the worker continues without that file. The worktree is still usable; the thread may fail later if it actually needs the missing path.
  • Conflicts with thread output. Symlinked paths share state with the source. If two threads write to the same symlinked directory at once, last write wins. For anything threads will mutate, prefer copy, or do not sync it at all and let the thread regenerate it.

Read next