boost / docs / adapters · boost adapt

New command · boost adapt <skill> --to <framework>

# One authored skill, every agent framework.

boost installs skills as files for editor-style agents — Claude Code, Cursor, Windsurf, Gemini CLI. But frameworks like CrewAI and the OpenAI Agents SDK aren't editors watching a folder; an agent there is a value constructed in a Python source file. `boost adapt` bridges that gap: it renders one `SKILL.md` into each framework's native idiom — a deterministic, zero-dependency string transform that never imports the framework it targets.

2 Frameworks rendered
97.6%Mutation kill on the renderer
56 Unit + functional tests
0 Runtime dependencies added
The idea, plainly

## Author once. Distribute anywhere. No drift.

A skill's value is its instructions. Today those instructions can only reach agents that read a skills directory. Copy them by hand into a CrewAI or LangGraph app and you now maintain two, three, four divergent copies — and the moment the checklist changes, they skew. `boost adapt` makes boost the single distribution point: the skill lives in one versioned `SKILL.md`, and each framework gets a freshly-rendered copy on demand.

- Kills drift. One source of truth; re-run `boost adapt` after any edit and every framework picks up the change.
- Grows the audience. `boost search` / `install`'s whole catalog becomes reachable from CrewAI and Agents-SDK shops, not just editor plugins.
- Governance travels. The exported agent inherits which version, from which tap, pinned to which SHA — provenance those frameworks have no native answer for.
- Zero dependency cost. Each renderer emits text; boost never imports CrewAI or LangGraph, so the zero-dep runtime contract holds.

Architecture

## Two lanes out of one skill

The existing install lane copies `SKILL.md` verbatim into folders that editor agents watch. The new adapt lane transforms the same skill into framework source. Same input, two consumers — files for editors, code for frameworks.

Sequence

## What happens on boost adapt code-reviewer --to crewai

Resolution prefers the installed store, then falls back to any tap clone — so you can adapt a skill you haven't installed. The framework is never imported; the last step (instantiating the agent) runs only in your app, out of boost's process.

Technical · the contract

## How a skill maps onto each framework

Every renderer is a pure function `(name, description, body) → str`. The three skill fields map onto each framework's constructor kwargs. Nothing else is invented — the body is the agent's instructions.

boost skill field | CrewAI `Agent(…)` | OpenAI Agents SDK `Agent(…)`
--- | --- | ---
`name` | `role` | `name`
`description` | `goal` | `handoff_description`
markdown `body` | `backstory` | `instructions`

### The escaping defense

A skill body full of quotes, backslashes or `"""` is what breaks a naïve template. The renderer emits every string via `json.dumps(s, ensure_ascii=False)` — JSON string syntax is a subset of Python's, so the result is always a valid, safely-escaped Python literal, with non-ASCII left readable.

### The identifier rule

The assignment target is derived from the skill name: `code-reviewer → code_reviewer`. A leading digit or a Python keyword gets an `s_` prefix, so the emitted variable always parses. `_ident()` is proven to return a valid identifier for every input.

    # boost adapt code-reviewer --to crewai
    # Generated by `boost adapt code-reviewer --to crewai`. Do not edit by hand.
    from crewai import Agent

    code_reviewer = Agent(
        role="code-reviewer",
        goal="Reviews a diff for correctness, security, and test coverage",
        backstory="Review the provided diff.\nFlag: unhandled errors, ...",
    )

Validation

## What the gate can prove — and what it can't

boost stays zero-dependency, so CI never installs CrewAI. That draws a hard line through the test strategy: everything provable without the framework runs in the release gate; the one thing that needs the framework runs opt-in, and can never flake a release.

In the gate · stdlib only

### Deterministic + valid Python

- Byte-exact golden output — any template mutation changes the string and fails a test.
- compile() every emitted source, incl. adversarial bodies (quotes, `"""`, backslashes, unicode).
- ast round-trip — the body literal decodes back to the original.
- 97.6% mutation kill on `core/adapters.py`; full CLI paths in functional tests.

Out of the gate · framework installed

### Does the live API accept it?

- `adapter-conformance.yml` — a matrix job that `pip install`s each framework and imports the emitted file to instantiate a real `Agent`.
- Runs on manual dispatch + weekly cron — never on PRs, so it can't redden a PyPI release.
- Pinned to Python 3.13: CrewAI's `tiktoken` has no 3.14 wheel — the frameworks, not boost, set the ceiling.
- Verified against crewai 1.15.5 and the OpenAI Agents SDK — both instantiate cleanly.

The honest boundary. `make check` proves the transform is deterministic, byte-exact, valid Python, escaping-safe, and the CLI behaves. It does not prove CrewAI's live API accepts the output — that verification is real, but it lives with the dependency we don't control, never in the release gate.
Try it locally

## From a boost skill to a running CrewAI agent

    # 1 — render the skill to CrewAI source (nothing installed needed)
    boost adapt code-reviewer --to crewai -o reviewer.py

    # 2 — in a throwaway venv, install the framework and load it
    python3 -m venv /tmp/crew && /tmp/crew/bin/pip install "crewai[anthropic]"
    /tmp/crew/bin/python -c "import reviewer; print(reviewer.code_reviewer.role, reviewer.code_reviewer.llm.model)"
    # → code-reviewer claude-haiku-4-5-20251001   ✦ imported, instantiated, on boost's model

Runs on boost's model by default. With no `--model`, the exported agent is wired to boost's configured `ai.model` (Claude) via each framework's LiteLLM path — so it runs on the same LLM boost uses, no OpenAI key. Override with `--model openai/gpt-4o`, or `--model none` for the framework's own default. (The `[anthropic]`/`[litellm]` extras carry that provider.)

Supported targets today: `crewai`, `agents-sdk`. Adding another framework is one `render_*` function plus a row in the `FORMATS` registry and its golden test.