{"_id":"@avee1234/handover","_rev":"3-08e9c7d20757c44d98c295f9d11adf75","name":"@avee1234/handover","dist-tags":{"latest":"0.2.1"},"versions":{"0.1.0":{"name":"@avee1234/handover","version":"0.1.0","keywords":["ai","agent","handoff","resume","checkpoint","task-state","interchange","multi-agent","portable","zero-dependency","claude-code","codex","cursor","antigravity"],"license":"MIT","_id":"@avee1234/handover@0.1.0","maintainers":[{"name":"avee1234","email":"das.abhijit34@gmail.com"}],"bin":{"handover":"bin/handover.js"},"dist":{"shasum":"0a2c915354e8533787e640d4f35806f50a209a10","tarball":"https://registry.npmjs.org/@avee1234/handover/-/handover-0.1.0.tgz","fileCount":14,"integrity":"sha512-jcyoyaOujry7i9YBiOSl5dkq/MnxhUyBjSCzBtFDShghF8TQ17H3zzfAWOd5THjcFm2SJAmfiZ5gOe1uPNG7xg==","signatures":[{"sig":"MEUCIQC+JSdb7aEP/PG4eH3yk96Ak4KM6g5AxX6v4EuoA3E/nwIgJhGenOsbEj8dR8cscTkJosIKcwXwUllTW4X7gQ+u8D4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":62654},"main":"src/index.js","type":"module","engines":{"node":">=18"},"gitHead":"422dcebb0269ddc969681f299d66ffcdb24180de","scripts":{"test":"node --test"},"_npmUser":{"name":"avee1234","email":"das.abhijit34@gmail.com"},"_npmVersion":"10.9.8","description":"The open format for handing off an in-progress agent task. A portable, harness-neutral JSON packet capturing everything a fresh agent needs to RESUME a task mid-flight — goal, context, progress, working state, next steps, open questions, and artifacts — s","directories":{},"_nodeVersion":"22.22.3","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/handover_0.1.0_1784000395183_0.342855254337604","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@avee1234/handover","version":"0.2.0","keywords":["ai","agent","handoff","resume","checkpoint","task-state","interchange","multi-agent","portable","zero-dependency","claude-code","codex","cursor","antigravity","adapter","session-handoff"],"license":"MIT","_id":"@avee1234/handover@0.2.0","maintainers":[{"name":"avee1234","email":"das.abhijit34@gmail.com"}],"bin":{"handover":"bin/handover.js"},"dist":{"shasum":"e7dc0d4a0cf23a6410072b2da730dad128a841e8","tarball":"https://registry.npmjs.org/@avee1234/handover/-/handover-0.2.0.tgz","fileCount":18,"integrity":"sha512-BnxRfEJmcnDi608avE4D29h0jgsle1+bwZPi+6TSCkT0alJ5KWT4JN/Dkv9A+uvioyPE0rod7b/9t9m3P4aU/A==","signatures":[{"sig":"MEUCIQDk5VNj1CXHc9DwYC3ikpO39sRp6ir0n60CaGKsTphSnwIgdqe0SxDImWDTR0u93yMMu92Xh1L28x+rKXNL24A8cjY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":87014},"main":"src/index.js","type":"module","engines":{"node":">=18"},"gitHead":"916e430cc979a0369d123d60ee559cffda7972ab","scripts":{"test":"node --test"},"_npmUser":{"name":"avee1234","email":"das.abhijit34@gmail.com"},"_npmVersion":"10.9.8","description":"The open format for handing off an in-progress agent task. A portable, harness-neutral JSON packet capturing everything a fresh agent needs to RESUME a task mid-flight — goal, context, progress, working state, next steps, open questions, and artifacts — s","directories":{},"_nodeVersion":"22.22.3","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/handover_0.2.0_1784054649142_0.2767770105371381","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@avee1234/handover","version":"0.2.1","description":"The open format for handing off an in-progress agent task. A portable, harness-neutral JSON packet capturing everything a fresh agent needs to RESUME a task mid-flight — goal, context, progress, working state, next steps, open questions, and artifacts — s","type":"module","main":"src/index.js","bin":{"handover":"bin/handover.js"},"engines":{"node":">=18"},"scripts":{"test":"node --test"},"keywords":["ai","agent","handoff","resume","checkpoint","task-state","interchange","multi-agent","portable","zero-dependency","claude-code","codex","cursor","antigravity","adapter","session-handoff"],"license":"MIT","gitHead":"525824016d8c4438016353eac33506b755ef226b","_id":"@avee1234/handover@0.2.1","_nodeVersion":"25.8.0","_npmVersion":"11.11.0","dist":{"integrity":"sha512-vUj/ZN+6p3lNHmtAq8bSyoF2iVNm6n2YwnGYE9o7r1y3nfPD4Ue4LHVCq6v4FsQ/TZqkFFogrDv4JoPRv1BUGA==","shasum":"40676943fdc713ccbd2d5827226350dba1714769","tarball":"https://registry.npmjs.org/@avee1234/handover/-/handover-0.2.1.tgz","fileCount":19,"unpackedSize":91028,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCfNtz1D8+ZhlEa1rAh/wq6R0zONqNo2WTcTA4QIPGiJQIhAJH2nBr/5EsP8c27nIaiNTeKtRBPrpEEYl4gxYzwuXwg"}]},"_npmUser":{"name":"avee1234","email":"das.abhijit34@gmail.com"},"directories":{},"maintainers":[{"name":"avee1234","email":"das.abhijit34@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/handover_0.2.1_1784123955012_0.04071856505078775"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-14T03:39:55.045Z","modified":"2026-07-15T13:59:15.270Z","0.1.0":"2026-07-14T03:39:55.339Z","0.2.0":"2026-07-14T18:44:09.303Z","0.2.1":"2026-07-15T13:59:15.162Z"},"license":"MIT","keywords":["ai","agent","handoff","resume","checkpoint","task-state","interchange","multi-agent","portable","zero-dependency","claude-code","codex","cursor","antigravity","adapter","session-handoff"],"description":"The open format for handing off an in-progress agent task. A portable, harness-neutral JSON packet capturing everything a fresh agent needs to RESUME a task mid-flight — goal, context, progress, working state, next steps, open questions, and artifacts — s","maintainers":[{"name":"avee1234","email":"das.abhijit34@gmail.com"}],"readme":"# handover\n\n**The open format for handing off an in-progress agent task.** When an agent has to stop mid-flight — context window full, session ending, a better-suited model or harness needed, a human stepping away — it writes a *handover packet*: a single portable JSON document capturing everything a fresh agent needs to *resume* the work exactly where it stopped. The goal, the constraints, what's been done, the live working state, what's next, what's still unknown, and the artifacts in play. So an in-progress task can move between agents or harnesses without losing its state. Zero dependencies.\n\n> Working name — see [`vision.md`](vision.md). Grounded in the mid-2026 state of long-running agent tasks.\n\nLong-running agent tasks routinely outlive a single agent. A coding job spans more context than one window holds; a session hits its limit; the work would go faster on a different model; a human hands the thread to a teammate's agent overnight. Coding agents — Claude Code, Codex, Cursor, and Google Antigravity — all hit this wall. Today, when that handoff happens, **the working state evaporates.** The next agent gets a cold transcript (if anything) and re-derives the plan, re-reads the files, re-discovers the decisions already made — or silently drops a half-finished thread. `git blame` doesn't hold it; a chat transcript is lossy and harness-specific; every harness that gestures at \"resume\" or \"session export\" does it in its own private, non-portable shape.\n\n> A2A standardizes how one agent *invokes* another. Nothing standardizes the *working state* an agent hands over when it stops mid-task — so every resume starts from scratch.\n\nhandover is the missing layer: an open format for the *working state handed over between two agents*, not another orchestrator, memory store, or runtime.\n\n```bash\nnpx @avee1234/handover pack --goal \"add PKCE to login\" --agent me   # capture the current handoff\nnpx @avee1234/handover completeness .handover/packet.json           # is this good enough to resume from?\nnpx @avee1234/handover resume .handover/packet.json                 # render the briefing for a fresh agent\nnpx @avee1234/handover diff old.json new.json                       # what did one checkpoint advance over another?\nnpx @avee1234/handover from claude-code transcript.jsonl            # draft a packet from a native session (any harness)\n```\n\n**Why it's different:** content-addressed, so a packet is self-identifying — its `id` is the sha256 of its content, so any edit produces a new identity and a resumed packet is provably the one that was handed off. It's a **single living document**, not a ledger — no registry to fold, no server to run. Harness-neutral: Claude Code, Codex, Cursor, Google Antigravity, or a factory worker — anything that can run a CLI or import a function.\n\nSame open-format playbook as [opentrajectory](https://github.com/abhid1234/opentrajectory) (traces), [provenant](https://github.com/abhid1234/provenant) (provenance), and [worklease](https://github.com/abhid1234/worklease) (coordination) — the standard for the one thing a mid-task agent handoff currently lacks: *a portable working-state document.*\n\n## The packet format\n\nA handover packet is one JSON document. `id` is the sha256 content hash of the record itself (its own `id` excluded), so a record's identity *is* its content. `goal` and `provenance` are the required spine; every other section is optional but type-checked when present.\n\n```json\n{\n  \"id\": \"19483d7ee3c50e5f4ee2507643f205e9c6f28bc6f972e04bece928519b4a3374\",\n  \"version\": 1,\n  \"goal\": \"add PKCE to the OAuth login flow\",\n  \"context\": \"Zero new deps. The auth module must stay framework-agnostic.\",\n  \"progress\": [\n    \"wrote the PKCE verifier/challenge helpers\",\n    \"wired them into the /authorize handler\"\n  ],\n  \"state\": {\n    \"cursor\": \"src/auth/login.ts:142\",\n    \"approach\": \"S256 challenge\",\n    \"key_files\": [\"src/auth/login.ts\", \"src/auth/pkce.ts\"]\n  },\n  \"next_steps\": [\n    \"handle the token-exchange callback\",\n    \"add tests for the verifier\"\n  ],\n  \"open_questions\": [\"should we fall back to plain challenge for legacy clients?\"],\n  \"artifacts\": [{ \"path\": \"src/auth/pkce.ts\", \"note\": \"new helper module\" }],\n  \"provenance\": {\n    \"handed_off_by\": \"claude-opus-4-8/claude-code\",\n    \"created\": \"2026-07-11T12:00:00Z\",\n    \"from_session\": \"sess-9f21\"\n  }\n}\n```\n\n- `goal` — **the task** being handed off (required, non-empty).\n- `context` — constraints, background, and decisions the resumer must respect.\n- `progress` — what's already been done (array of notes).\n- `state` — the live working state (free-form object); an optional `key_files` array names the files to open first.\n- `next_steps` — what to do next.\n- `open_questions` — what's still unresolved.\n- `artifacts` — `{ path, hash?, note? }` for the files produced or touched; `hash` (if present) is the sha256 of the file's bytes.\n- `provenance` — **who** handed off (`handed_off_by`), **when** (`created`, ISO-8601-**UTC**, `…Z`; offsets and impossible calendar dates are rejected), and optionally the originating `from_session`.\n- `version` — the checkpoint number, incremented by `revise`.\n\n## Library API\n\nZero-dependency ESM. `import { … } from \"@avee1234/handover\"`. Every function is pure and clock-injected (no I/O except the packet store), so the whole core is deterministic and unit-testable.\n\n**Schema & validation** — never throw; each returns `{ valid, errors }` collecting *every* violation.\n- `validatePacket(obj)` / `validateArtifact(obj)`\n- `isSha256Hex(s)`, `isIso8601Utc(s)` — the two format primitives\n- `PACKET_FIELDS`, `REQUIRED_SECTIONS`, `ERROR_CODES`\n\n**Construct** — pure packet constructors (throw on bad input rather than emit a malformed packet).\n- `pack(input)` → a validated packet with a content-hash id and all section defaults applied. `input` is `{ goal, agent, created, context?, progress?, state?, next_steps?, open_questions?, artifacts?, from_session?, version? }`; `created` is injected (no clock inside).\n- `revise(packet, patch)` → a NEW checkpoint: `version` incremented, array sections **appended**, scalar sections (`goal`, `context`) **replaced** when present, `state` shallow-merged, provenance refreshed (`patch.created` required — a revision is a fresh handoff).\n\n**Hash & id** — the content-address primitives.\n- `computeId(record)` → the sha256 content hash of a record (its own `id` excluded)\n- `canonicalize(record)` → the deterministic hash pre-image (sorted keys, recursive)\n- `computeHash(content)` → the sha256 hex of a string/Buffer (an artifact fingerprint for `artifacts[].hash`)\n\n**Assess & render** — pure, total, over a single packet.\n- `completeness(packet)` → `{ score, total, present, missing, warnings }` — how much of the handoff a fresh agent has to work with, over the seven `REQUIRED_SECTIONS`, plus plain-language warnings about gaps that strand a resumer.\n- `resume(packet)` → the Markdown briefing a fresh agent can be handed verbatim (goal, context, what's done, live state + key files, next steps, open questions, artifacts, and a provenance footer).\n- `resumeInto(packet, harness)` → the same briefing in a harness's opening-context **shape**: `'system-prompt'` (a system-prompt string), `'user-turn'` (a first-user-message string), or `'mcp-resource'` (`{ uri, mimeType: 'text/markdown', text }`). The Markdown body is the real `resume()` output in every shape; an unknown shape throws (the supported shapes are in `RESUME_SHAPES`).\n- `summarize(packet)` → a one-line status: `\"<goal> — N done, M next, K open\"`.\n- `diffPackets(a, b)` → what checkpoint `b` advanced over `a`: `{ goal_changed, version_delta, progress_added/removed, next_steps_added/removed, questions_opened/closed, artifacts_added/removed, state_keys_changed }` (set semantics on the string arrays — reordering reads as no change).\n\n**Packet store** — the single-document I/O layer.\n- `savePacket(path, packet)` → write the packet as pretty JSON (creating its parent dir); overwrites in place — a packet is one living document, not an append log.\n- `loadPacket(path)` → the parsed packet (clear throw on a missing file or malformed JSON).\n- `defaultPacketPath(cwd)` → `HANDOVER_PACKET`, else `.handover/packet.json`.\n\n**Adapters** — seed a draft packet from a harness's native session artifact so writing one is cheap. Every adapter shares one contract: `(raw, opts) → draftPacket` — latest user message → `goal`, last assistant turn → `context`, assistant bullet/numbered lines → `progress`. All are pure and tolerant of malformed input, and all return a PARTIAL draft (no `id`, no `created`) — **not** a validated packet. Refine it, then `pack()`. `opts` is `{ agent?, from_session?, max_progress? }`.\n- `fromClaudeCode(rawJsonlTranscript, opts)` → draft from a Claude Code `.jsonl` session transcript.\n- `fromCodex(rawJsonlRollout, opts)` → draft from an OpenAI Codex CLI `.jsonl` rollout (unwraps the `payload` envelope; reads `input_text` / `output_text` blocks).\n- `fromCursor(rawSession, opts)` → draft from a Cursor chat export (whole-document JSON, `.jsonl`, `User:`/`Assistant:` prose, or a marker-less scratchpad).\n- `fromAntigravity(rawSession, opts)` → draft from a Google Antigravity session (JSON / `.jsonl` / prose) or an `AGENTS.md`-style task brief (headings → goal, bullets → progress).\n- `ADAPTERS`, `getAdapter(name)` — the name→builder registry keyed `claude-code` / `codex` / `cursor` / `antigravity` (add new harnesses here).\n\n## CLI\n\n```bash\nhandover pack [--file <in.json>] [--agent <id>] [--goal \"<task>\"] [--out <path>] [--json]\nhandover show <file> [--json]\nhandover validate <file> [--json]\nhandover completeness <file> [--json]\nhandover resume <file>\nhandover diff <a> <b> [--json]\nhandover from <harness> <file> [--agent <id>] [--json]\nhandover from-<harness> <file> [--agent <id>] [--json]\n```\n\n- **`pack`** — read a JSON object (from `--file` or stdin), fill section defaults, stamp the handoff (agent + timestamp), validate, and write the packet. `--goal` / `--agent` override the input; the clock is read only here. Writes to `--out` (default: `HANDOVER_PACKET`, else `.handover/packet.json`).\n- **`show`** — pretty-print a packet (`--json`), or a one-line summary without it.\n- **`validate`** — validate a packet against the schema. Exit `0` if valid, `1` otherwise (errors listed with their paths and codes).\n- **`completeness`** — score how much of the handoff a fresh agent has to work with, and warn about the gaps that strand a resumer.\n- **`resume`** — render the Markdown briefing a fresh agent can be handed verbatim.\n- **`diff`** — show what checkpoint `<b>` advanced over checkpoint `<a>`.\n- **`from`** — resolve a harness adapter from the registry (`claude-code`, `codex`, `cursor`, `antigravity`) and parse its native session artifact into a DRAFT packet to refine and pipe back into `handover pack`. `from-<harness>` (e.g. `from-claude-code`) is the shorthand form.\n\nCommon flags: `--agent <id>` (or `HANDOVER_AGENT`), `--out <path>` (or `HANDOVER_PACKET`, default `.handover/packet.json`), `--json` for machine-readable output.\n\n## Install\n\n```bash\nnpm install @avee1234/handover      # library\nnpx @avee1234/handover pack …       # CLI, no install\n```\n\nRequires Node ≥ 18. Run the test suite with `node --test`.\n\nStatus: **v0.2** — multi-harness adapters (Claude Code, Codex, Cursor, Google Antigravity) + `resumeInto`. See [`roadmap.md`](roadmap.md). MIT · zero dependencies · harness-neutral.\n","readmeFilename":"README.md"}