.handoff/ Runtime State
What Handoff stores in the workspace's local .handoff/ directory, and why it's gitignored.
.handoff/ is where the CLI keeps everything that's local-machine state rather than
version-controlled content. It should always be gitignored.
| Path | Purpose |
|---|---|
.handoff/cli-auth.json | Saved OAuth device-flow credentials (remoteUrl, accessToken, expiresAtMs) written by handoff-app login / mcp-init, read by push/pull/sync-status/mcp-token so you don't have to re-authenticate on every command. Removed by handoff-app logout. |
.handoff/sync-state.json | The last sync cursor (lastSyncVersion, lastSyncAt) and a per-entity fingerprint map, used by push (to skip unchanged components) and pull/sync-status (to compare local vs. remote state). |
.handoff/conflicts/ | Where pull writes files it couldn't cleanly merge into the workspace, for manual resolution. |
.handoff/.cache/build-cache.json | Component build cache: per-component source/template file states plus a global-deps state (the token snapshot, global SCSS, global JS). Tokens are one invalidation input, not the key — the cache is what lets start and the build commands skip components whose sources haven't changed. |
.handoff/app/ | Where the Next.js app is materialized under the default materialization_layout: 'legacy'. The other two layouts put it elsewhere: 'runtime' → <workingPath>/handoff-runtime, 'root' → the workspace root itself. (.handoff/runtime/ is a separate, ephemeral CI root used by the deprecated prepare-runtime/vercel-build per-project deploy path, not a materialization_layout value.) |
Always gitignore .handoff/
It holds a bearer token (cli-auth.json) and machine-local cache/state, never commit it.
mcp-init --embed also writes into a project's .mcp.json, not .handoff/, but adds that file
to .gitignore for you when it embeds a literal token; do the same for .handoff/ if your
workspace template doesn't already ignore it.
None of this is required for a workspace to function from scratch, delete .handoff/ at any
time and the CLI will recreate what it needs (you'll just need to login again and push
without the unchanged-file skip optimization on the next run).