{"id":50705260,"url":"https://github.com/givepro91/cc-handoff","last_synced_at":"2026-06-09T11:01:25.577Z","repository":{"id":363430679,"uuid":"1257887751","full_name":"givepro91/cc-handoff","owner":"givepro91","description":"Never lose context between Claude Code sessions — hook-enforced session handoff to a git-tracked HANDOFF.md, portable across machines.","archived":false,"fork":false,"pushed_at":"2026-06-08T21:17:27.000Z","size":20,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-08T23:14:15.313Z","etag":null,"topics":["ai","claude-code","claude-code-plugin","context-management","developer-tools","handoff","hooks","llm"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/givepro91.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-03T05:08:02.000Z","updated_at":"2026-06-08T21:17:27.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/givepro91/cc-handoff","commit_stats":null,"previous_names":["givepro91/cc-handoff"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/givepro91/cc-handoff","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/givepro91%2Fcc-handoff","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/givepro91%2Fcc-handoff/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/givepro91%2Fcc-handoff/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/givepro91%2Fcc-handoff/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/givepro91","download_url":"https://codeload.github.com/givepro91/cc-handoff/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/givepro91%2Fcc-handoff/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34103357,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-09T02:00:06.510Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","claude-code","claude-code-plugin","context-management","developer-tools","handoff","hooks","llm"],"created_at":"2026-06-09T11:01:23.496Z","updated_at":"2026-06-09T11:01:25.567Z","avatar_url":"https://github.com/givepro91.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# cc-handoff\n\n\u003e Never lose context between Claude Code sessions — even across machines.\n\nA [Claude Code](https://docs.claude.com/en/docs/claude-code) plugin that automatically preserves a session's **decisions, open work, and next steps** into a git-tracked, **per-branch** handoff (`docs/handoff/\u003cbranch\u003e.md`), so the next session — on this machine or another, on the same branch — picks up exactly where you left off.\n\n## The one-line design\n\n\u003e **Tools live machine-global. Data lives in the repo (git).**\n\n`--resume`, auto memory, and `/rewind` checkpoints all live under `~/.claude` on a *single machine* — they don't follow a `git push` to your other laptop. So the canonical handoff is a file that travels with the repo.\n\n## Why this exists\n\n- **`/compact` is lossy.** Anthropic states it plainly: *\"overly aggressive compaction can result in the loss of subtle but critical context whose importance only becomes apparent later.\"* Decisions and the *why* behind them are exactly what gets dropped.\n- **Manual and model-discretion handoffs forget.** If you have to remember to run `/handoff`, you eventually won't — and a crashed/closed session takes everything with it.\n- **Hooks don't forget.** A `Stop` hook can return `decision: \"block\"` with a `reason` that becomes the model's next instruction — the one robust way to *force* the handoff to be written when work happened but wasn't recorded.\n\n## How it works — a hybrid of hooks\n\n| Hook | When | What it does |\n|------|------|--------------|\n| `SessionStart` | startup / resume / clear / compact | Injects **the current branch's** handoff into context — **auto-restore** (blocked ones prominently; resolved/deleted ones not at all; auto-migrates a legacy `HANDOFF.md` on first run) |\n| `PreCompact` | right before compaction | Backs up the raw transcript (per-branch) + a git breadcrumb to `docs/handoff/.snapshots/` — **loss protection** |\n| `Stop` | end of a turn | If ≥N files changed *and* the branch handoff is stale, blocks **once** and asks the model to write it — **never-miss enforcement** |\n| `/handoff` skill | manual | Write this branch's handoff (`blocked` to flag it), or `/handoff status` · `/handoff resolve` (delete when done) · `/handoff prune` (clear orphans) |\n\n**Honest limitation:** there is no way to make the model write an intelligent handoff at the exact instant you close the terminal — `SessionEnd` hook output is ignored. Instead this catches turn-end and pre-compaction, which covers virtually every real case.\n\n## Parallel branches \u0026 worktrees\n\nRun many sessions at once (Boris-style: several local + a few on the web) and a single shared handoff falls apart — it gets overwritten and you can't tell which one is latest or already resolved. v2 fixes that:\n\n- **One handoff per branch** — `docs/handoff/\u003cbranch\u003e.md` (slug-sanitized, e.g. `feat/login` → `feat-login.md`). Each worktree only ever writes its own branch file, so there's **no disk or merge conflict**.\n- **`SessionStart` injects only the current branch's** handoff — no cross-branch noise.\n- **Derived status board** — `/handoff status` scans the files and shows status/age/issue per branch (🟢 active · ⛔ blocked), marking the current branch, plus any **prunable** orphans. There is **no committed index file** (that would conflict on merge) — the board is always derived on demand.\n- **Ephemeral by design** — a handoff exists only while work is open. **`/handoff resolve`** deletes a finished branch's handoff (git history keeps it); **`/handoff prune`** clears handoffs whose branches were merged/deleted — so files never pile up on `main`.\n\n```\n🟢 feat-login   (current)  2h ago   #42\n⛔ fix-cache    BLOCKED     1d ago   #51\n\nprunable: chore-old (branch merged) — run /handoff prune\n```\n\nUpgrading from v1? The legacy single `docs/handoff/HANDOFF.md` is **auto-migrated** to the current branch's file on first run (lossless — the legacy file is left in place; delete it once you've confirmed).\n\n## Install\n\n```sh\n# Add this repo as a marketplace, then install (user scope = available in every project)\n/plugin marketplace add givepro91/cc-handoff\n/plugin install handoff@cc-handoff\n```\n\nOr from a local clone:\n\n```sh\n/plugin marketplace add /path/to/cc-handoff\n/plugin install handoff@cc-handoff\n```\n\n## Enable per project (opt-in)\n\nInstalling the plugin does **not** disturb any project on its own. A project opts in by having a `docs/handoff/` directory — without it, every hook stays silent.\n\n```sh\n/handoff        # creates docs/handoff/ + this branch's handoff → hooks activate from then on\n```\n\nOptionally, pin it in your project `CLAUDE.md` / `AGENTS.md` so new sessions read it first:\n\n```\nAt session start, if a handoff for the current branch exists under docs/handoff/, read it first and continue from \"Next steps\".\n```\n\n## Configuration\n\n| Env var | Default | Meaning |\n|---------|---------|---------|\n| `HANDOFF_MIN_CHANGED_FILES` | `3` | Minimum changed files before the `Stop` hook will block |\n| `HANDOFF_STOP_ENFORCE` | _(on)_ | Set to `0` to disable `Stop` enforcement (snapshot + restore still run) |\n\n## Data layout\n\n- `docs/handoff/\u003cbranch\u003e.md` — **git-tracked.** One canonical handoff per branch; travels across machines via commit + push.\n- `docs/handoff/HANDOFF.md` — legacy single file (v1). Auto-migrated to the branch file on first run; safe to delete afterwards.\n- `docs/handoff/.snapshots/` — **git-ignored** (added automatically). Lossless per-branch pre-compaction backups, local to the machine.\n\nThe status board is **derived** (`/handoff status`) — there is no index file to commit or conflict on.\n\nKeep the detailed *why* of each decision in your **commit messages** (`git log` is portable too); keep open work and next steps in the branch handoff.\n\n## What a handoff looks like\n\n```markdown\n---\nbranch: feat/login\nstatus: active            # active | blocked  (done = file deleted)\nupdated: 2026-06-08T12:00:00.000Z\nissue: 42                 # optional\npr: 51                    # optional\n---\n\n# Handoff — \u003ctask\u003e · \u003cdate\u003e · \u003cmachine\u003e\n\n## Restore in 30s\nWhat you were doing / where you got to / what you just finished.\n\n## Next steps\n- [ ] Concrete next action — down to files \u0026 commands\n- [ ] Blocker + what was already tried\n- [ ] Parked item + why\n\n## Touch points\n- path/to/file:line — what / why · verify: `command` → expected\n\n## Decisions\n- \u003cdecision\u003e → detailed why in commit `\u003chash\u003e`\n```\n\n## Project structure\n\n```\ncc-handoff/\n├── .claude-plugin/marketplace.json      # marketplace manifest\n└── plugins/handoff/\n    ├── .claude-plugin/plugin.json       # plugin manifest\n    ├── hooks/\n    │   ├── hooks.json                   # registers SessionStart · PreCompact · Stop\n    │   ├── _lib.mjs                      # shared helpers\n    │   ├── session-start.mjs            # restore\n    │   ├── pre-compact.mjs              # snapshot\n    │   └── stop.mjs                     # never-miss enforcement (medium)\n    └── skills/handoff/SKILL.md          # /handoff manual capture\n```\n\nHooks are plain Node ESM (no dependencies). Requires a recent Node on `PATH`.\n\n## License\n\nMIT © 2026 Jay (Spacewalk)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgivepro91%2Fcc-handoff","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgivepro91%2Fcc-handoff","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgivepro91%2Fcc-handoff/lists"}