Metadata-Version: 2.4
Name: handoffpack
Version: 0.1.0
Summary: Deterministic structured handoff-card codec + MCP translator server for agent handoffs, session compaction, and instruction compilation (client-side sampling for semantics; zero server-side LLM cost).
Author: Myeong Jun Jo
License: LicenseRef-Proprietary
Project-URL: Homepage, https://github.com/myeongjunjo/handoffpack
Project-URL: Repository, https://github.com/myeongjunjo/handoffpack
Keywords: mcp,model-context-protocol,llm,agent,handoff,context-compaction,prompt-compression,claude
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: Other/Proprietary License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: mcp>=1.0
Requires-Dist: cryptography>=42
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"

# handoffpack — MCP structured-card translator

Deterministic codec + guards + MCP server for HP1 structured handoff cards.
Turns agent handoffs, session logs, and recurring-instruction files into
compact structured cards. All deterministic work runs locally; the server
never calls an LLM API and holds no API keys.

## Install

Python 3.11+ required.

```bash
# From PyPI (once published):
pip install handoffpack

# Pre-publish / local: from the package directory
pip install .
# or editable, with test deps:
pip install -e .[dev]
```

Core codec/guards tests run with stdlib + pytest only; the `mcp` package
is needed only to run `server.py`.

## Register the MCP server (Claude Code)

```bash
python -m handoffpack.server                       # stdio transport, run directly
claude mcp add handoffpack -- python -m handoffpack.server
```

Other clients (Cursor, etc.): use the same command in their MCP server
registration UI. A `handoffpack` console script is also installed as an
alias for `python -m handoffpack.server`.

## License key (paid add-ons only)

The 4 MCP tools (`encode` / `decode` / `compact_to_l2l` / `verify`) are
FREE and unlimited. Only paid add-ons (e.g. the full `hp-instructions`
conversion run) require a key. The verifier is fully offline (embedded
Ed25519 public key, no phone-home). Key discovery precedence:

```bash
export HP_LICENSE=HP1.xxxxx...        # macOS/Linux
set HP_LICENSE=HP1.xxxxx...           # Windows
# or place the key on the first line of ~/.handoffpack/license
# or pass --license <KEY> to hp-instructions
```

`hp-instructions --check` (drift scan) is free; a full conversion run
requires a `plus`-tier key.

## Layout

```
mcp-translator/
├── pyproject.toml
├── src/handoffpack/
│   ├── legend.json    # public card schema (typed slots + kv pairs)
│   ├── codec.py       # assemble/parse/validate + chars/4 token estimator
│   ├── guards.py      # breakeven passthrough, BAN-field rule, nuance heuristic
│   ├── license.py     # offline Ed25519 license verifier (paid add-ons)
│   ├── adapter_instructions.py  # hp-instructions CLI (CLAUDE.md -> HP1 cards)
│   └── server.py      # MCP server: encode / decode / compact_to_l2l / verify
└── tests/
```

## Run tests

```bash
pytest        # 114 tests
```

## Build & publish (maintainer)

```bash
python -m build              # produces dist/*.whl + dist/*.tar.gz
python -m twine upload dist/*
```

If `build` is unavailable offline, an equivalent wheel can be produced
with `python -m pip wheel . -w dist --no-deps --no-build-isolation`.

## Architecture notes (caller-does-semantics)

- Deterministic work (card assembly, parsing, schema validation, guards,
  token estimation) is local and pure. The server never calls an LLM API
  and holds no API keys (zero-server-cost invariant).
- Semantic work (slot extraction, compaction keep/drop judgment) belongs
  to the CALLING model:
  - `encode(slots={...})` — the caller extracts TASK/ROLE/IN/DO/OUT/LIM/BAN
    from its own context and passes them directly (`mode: "slots"`,
    `confidence: "caller"`). Pass `text` too for token metrics.
  - `compact_to_l2l` — two-call protocol. Call 1 (`session_text` only)
    returns a per-segment `scaffold` + `fill_slots_and_recall` +
    a crude deterministic fallback. Call 2 adds
    `segment_slots={"<seg>": {slots} | "TASK string"}`.
  - `decode` / `verify` — deterministic.
- Freeform `encode(text=...)` without caller slots returns a deterministic
  skeleton card plus `fill_slots_and_recall` guidance for a second call.
- MCP sampling (`session.create_message`) survives only as an OPTIONAL,
  capability-detected upgrade path (deprecated upstream: MCP 2026-07-28
  spec RC, SEP-2577; replaced by Multi Round-Trip Requests, SEP-2322;
  Claude Code never implemented it, anthropics/claude-code#1785). It is
  OFF unless the operator sets `HP_ENABLE_SAMPLING=1` AND the client
  advertises the capability; results are always deterministically
  re-validated. Nothing depends on sampling.
- Token estimates use ceil(chars/4). Crude by design; never used for
  claims or billing.

## Guard behavior

- Inputs under ~70 estimated tokens are returned unchanged with a reason
  (encoding overhead exceeds savings below breakeven).
- BAN slots accept plain forbidden actions only. Conditional negation
  ("X unless Y", "only outside Z") is rejected; express the condition as
  a positive LIM constraint instead.
- Prose with high conditional-clause density gets an advise-skip verdict
  instead of a lossy card.
