Skip to content

Releases

0.2.2: why not just hermit convert, and #42 is closed

Choose a tag to compare

@argszero argszero released this 07 Nov 19:08

Documentation only: no module changed, so convert and deploy behave exactly as
in 0.2.1. Two questions the README left a reader to work out are now answered, and
one of its claims was out of date.

Why not just hermit convert?

A new section, measured on 2026-11-08 against hermit-harness 0.2.0 (still the
latest on PyPI) and upstream main at e79cbff:

$ hermit convert --adapter <adapter> --target opencode --output out/
hermit convert: error: argument --target: invalid choice: 'opencode'
                 (choose from claude-code, codex, pi, hermes)

Those four are EMITTERS in hermit/plugins/__init__.py, a hardcoded map with
TARGETS = tuple(EMITTERS) and no entry point, so a fifth host cannot be added
from outside hermit. The section also states what the standalone route costs: the
hermit-harness 0.2.0 floor, opencode 1.1.2 as the version the output was
load-checked on, and that deploy wants a workspace you already have.

The README said #42 was open. It is closed.

Relation to hermit's own OpenCode work described pull request #42 as "open and
conflicting when this was written". Read 2026-11-08, it is CLOSED and unmerged,
so the route inside hermit's core does not exist and this package is what remains
of it rather than a parallel option. The warning about both writing one workspace
is kept, because it is still the thing to avoid if a core route returns.

Install

pip install https://github.com/argszero/hermit-opencode/releases/download/0.2.2/hermit_opencode-0.2.2-py3-none-any.whl

Still needs hermit-harness 0.2.0 or later from PyPI to serve the embedded adapter.

Assets

hermit_opencode-0.2.2-py3-none-any.whl
  sha256 4df2583a7d1000e5c27a96481e8b42d317efcb5f5b922a8671dd9102ae3f7090
hermit_opencode-0.2.2.tar.gz
  sha256 5cd77c82d8d8eeb4c615e98125ea9ffd291616131f0cfcac99c7794e6d61c81d

26 tests pass with PYTHONPATH cleared; the deploy-then-opencode agent list
chain was re-run on 0.2.2 with the same result as 0.2.1.

0.2.1: an mcp entry opencode 1.1.2 accepts

Choose a tag to compare

@argszero argszero released this 06 Nov 19:02

0.2.1 fixes a configuration error that made opencode 1.1.2 refuse to start in a
deployed workspace, and replaces the caveat the previous release could only write.

The defect

0.2.0 wrote a cwd key into the mcp entry of opencode.json:

"file_example": {
  "type": "local",
  "command": ["hermit", "serve", ".opencode/adapter", "--audit-log", ".opencode/audit/tool-calls.jsonl"],
  "cwd": ".",
  "enabled": true
}

opencode 1.1.2 rejects that key and refuses the whole file:

$ opencode agent list
Error: Configuration is invalid at …/ws/opencode.json
↳ Invalid input mcp.file_example
EXIT CODE: 1

--print-logs --log-level DEBUG names the cause — Unrecognized key: "cwd".

A schema check could not have caught this. OpenCode's published JSON schema
still documents cwd for a local MCP server, and the copy committed under
tests/assets/ validates a configuration carrying it; the validator built into
1.1.2 is narrower than the schema the same project publishes. 0.2.1 emits the
entry without cwd, and the suite now pins the keys it may carry.

What this release proves, and what it does not

opencode 1.1.2 loads a workspace this tool deploys. opencode agent list there
exits 0 and lists the adapter's reviewer subagent after the CLI's seven
built-ins; the same command in an empty directory lists the seven and no
reviewer, so the eighth line is read from the deployed files.

Not proven: a model-driven session using those parts. No provider credentials
exist on the machine this was measured on, so nothing here shows a model
answering while calling the adapter's tool. opencode run and opencode auth login would close it; both need a provider account.

Install

pip install https://github.com/argszero/hermit-opencode/releases/download/0.2.1/hermit_opencode-0.2.1-py3-none-any.whl

Still needs hermit-harness 0.2.0 or later from PyPI to serve the embedded
adapter (pip install "hermit-harness>=0.2.0").

Assets

hermit_opencode-0.2.1-py3-none-any.whl
  sha256 f6bb6757ba81d6bf4c6281f29c5373eb446ad63e70d5e3655c4626a19c813813
hermit_opencode-0.2.1.tar.gz
  sha256 8c043fbfde8d40d15743251fc80f05585dfa1265cbd9bbb813be54ebbf8d54cc

Both were installed from the release URL and re-run before this note was
published. 26 tests pass with PYTHONPATH cleared.

0.2.0: deploy an adapter into a workspace, in place

Choose a tag to compare

@argszero argszero released this 06 Nov 06:49

deploy — the second half of hermit's OpenCode request.

0.1.x could only convert: emit a configuration into a directory of its own, which
you then copied into a project. This release adds the other route, which is what
hermit issue #35 and the
roadmap in #37 §3 ask for.

pip install https://github.com/argszero/hermit-opencode/releases/download/0.2.0/hermit_opencode-0.2.0-py3-none-any.whl
hermit-opencode deploy path/to/adapter --workspace /path/to/your/project

What deploy writes

The same four parts convert emits, in place: .opencode/context.md and its
instructions entry, .opencode/skills/, .opencode/agents/ (mode: subagent),
and opencode.json's mcp entry. Plus .opencode/adapter/ — its copy of the
adapter, namespaced there because a project may already have an adapter/
directory — and .opencode/hermit-opencode.json, the record that makes a
workspace this tool's own.

How it treats a tree that is not its own

  • It merges opencode.json; it never replaces it. Your other keys, your own
    instructions entries and your other MCP servers stay.
  • It refuses a workspace it did not create, and --force adopts one, printing
    which of its own files that adoption overwrote ("adopted": ["opencode.json"]).
  • It never deletes anything. A role or skill an earlier deploy wrote and the
    adapter no longer declares stays where it is; removing it is yours to do.
  • Two refusals hold even with --force, because merging is the only thing it does
    to your files and both mean it cannot merge: an opencode.json that is not valid
    JSON, and one whose instructions or mcp key holds the wrong type. It stops
    and names the file instead of overwriting what it could not read.
  • No managed block in AGENTS.md — the context travels as .opencode/context.md
    through instructions, which OpenCode combines with your AGENTS.md, so your
    file is never edited. No lifecycle hooks (refused, as convert refuses them,
    unless --allow-lossy), no container isolation, no per-task context_tool.

convert and 0.1.x's command spelling are unchanged: hermit-opencode <adapter> --output DIR still converts.

Which hermit this needs

Hermit is needed only for the tool server, and the mcp entry requires one that
reads the .hermit/adapter.yaml + exports.yaml layout: hermit-harness 0.2.0
or later
, from PyPI.

pip install "hermit-harness>=0.2.0"
python -c "from hermit.adapter import manifest; print(manifest.MANIFEST)"   # .hermit/adapter.yaml

hermit-harness 0.1.0 cannot serve the embedded adapter: its manifest reader wants
adapter.yaml at the adapter root, the layout hermit replaced in its own #41.
Nothing in convert or deploy needs hermit at all; only the server does.

What was verified

  • 25 tests pass, no network and no hermit installed. The new ones cover the
    four paths that matter in somebody else's tree: a fresh deploy; a second deploy
    that is byte-identical and leaves a user file, a user skill and the audit log
    untouched; a workspace this tool did not create, refused with nothing written;
    and --force adopting one and reporting what it overwrote.
  • A real deployment, then a real MCP exchange. A project holding its own
    main.py and AGENTS.md was adopted with --force; both survived byte for byte.
    The mcp command the deploy emitted was then run from the workspace with
    cwd: ".", PYTHONPATH cleared, under hermit-harness 0.2.0 from PyPI:
    initialize / tools/list / tools/call returned
    count_words('one two three') -> {"count": 3}, exit 0, and appended to
    .opencode/audit/tool-calls.jsonl inside the workspace.
  • The deployed opencode.json validates against https://opencode.ai/config.json
    (Draft202012, schema vendored in the repository), with cwd: "." and no absolute
    path anywhere in it.
  • The install command at the top was run from a clean virtualenv with
    PYTHONPATH cleared, so PyYAML 6.0.3 was genuinely fetched; both convert and
    deploy then ran from that install.

What was NOT verified

No live OpenCode session has ever loaded this output — convert's or
deploy's.
No OpenCode credentials or model backend were available, so the
end-to-end path stops at the MCP server: the configuration is schema-valid and its
server command works, but "OpenCode started, read .opencode/, and used the skill
and subagent" is unproven. A schema-valid configuration is not a loaded one.

deploy deserves that caveat more than convert does, because it writes into a
project you already have. Run it first in a fresh directory, or in a tree under
version control.

Assets

  • hermit_opencode-0.2.0-py3-none-any.whl — sha256 853b8097f5f3783ad8515b42007f2a89fc707161a1c350ac3e97fff0f3c56fd8
  • hermit_opencode-0.2.0.tar.gz — sha256 8c984a0d233c84e196ed7a98461a82268d49b614fdd2914f434660d9c231f246

0.1.1's tag and release are untouched. Its corrected notes still apply to that
version, including the withdrawal of the "install hermit from git" advice.

hermit-opencode 0.1.1 — installable wheel

Choose a tag to compare

@argszero argszero released this 04 Nov 18:32

Convert a hermit adapter into an OpenCode configuration.

pip install https://github.com/argszero/hermit-opencode/releases/download/0.1.1/hermit_opencode-0.1.1-py3-none-any.whl
hermit-opencode path/to/adapter --output out/

Why 0.1.1 exists

0.1.0's only documented install was pip install git+https://…. That needs a
git binary, a reachable git endpoint and a credential — and when it was tried
from a clean virtualenv it failed with Recv failure: Connection reset by peer.
There was no verified way for a stranger to install this. This release attaches
a wheel and an sdist, so installing is one HTTP download that involves no git.

An sdist is attached as well:
hermit_opencode-0.1.1.tar.gz.

Which hermit this needs — read this before you run it

Hermit is needed only for the tool server. The context, skills and roles
parts are plain files OpenCode reads directly and work with any hermit.

The mcp entry this tool emits — hermit serve adapter — requires a hermit that
reads the .hermit/adapter.yaml + exports.yaml layout: hermit-harness 0.2.0
or later
, from PyPI.

Correction, 2026-11-06. These notes first said to install hermit from git
main, because 0.1.0 was the only release and it cannot serve this output.
Hermit released 0.2.0 on 2026-11-04 — the release that moved the adapter metadata
into .hermit/ and stopped loading the 0.1 layout — so that advice is withdrawn:

pip install "hermit-harness>=0.2.0"

hermit-harness 0.1.0 cannot serve this output. Its manifest reader wants
adapter.yaml at the adapter root, the layout hermit replaced in its own #41, and
both the embedded copy and the source adapter use the newer layout — so no path,
flag or environment setting makes 0.1.0 serve it. The emitted command exits 1 with

ValueError: Missing adapter.yaml in <output>/adapter

Measured against 0.2.0 in a clean virtualenv, with no git binary and no checkout
involved: the same command served the tool and answered
count_words('one two three') -> {'count': 3}.

pip show hermit-harness now separates the two releases, and the manifest reader
is the mechanical check behind it:

python -c "from hermit.adapter import manifest; print(manifest.MANIFEST)"

.hermit/adapter.yaml → the tool server will start.
adapter.yaml → you have 0.1.0; the mcp entry will fail to start.

What was verified

  • The suite: 12 passed, no network, no hermit installed.

  • This wheel installs into an empty virtualenv and reports 0.1.1; import hermit still raises ModuleNotFoundError from a neutral directory, which is the zero-dependency claim measured rather than asserted.

  • opencode.json validates against https://opencode.ai/config.json (Draft202012, schema vendored in the repository).

  • The emitted mcp command was run from the output directory with cwd: "." under hermit cde2005: a real MCP initialize / tools/list / tools/call exchange returned count_words('one two three') -> {'count': 3} and appended to .opencode/audit/tool-calls.jsonl.

  • The requirement above is a measurement: the same command was run against hermit-harness==0.1.0 from PyPI (fails, message above) and against git main (succeeds). A test pins the emitted command and the README's Requirements table to each other.

  • The install command at the top of this page was run from an empty virtualenv: PYTHONPATH cleared (this machine exports one, which would otherwise supply dependencies the install never fetched), pip install <the wheel URL above> exited 0, PyYAML 6.0.3 was genuinely fetched from PyPI as a real dependency, the installed hermit-opencode reported 0.1.1, converting hermit's own example adapter exited 0, and the mcp command emitted from that output served count_words('one two three') -> {'count': 3} under hermit-harness 0.2.0. The wheel fetched from that URL hashes identically to the one built here (sha256 1ed6b22de17575346ee3239895f9b71600008d6e4070b498840939297a11c742), so the asset and the source agree.

hermit-harness 0.2.0 is the reading the requirement above rests on. 0.2.0 was published to PyPI on 2026-11-04, after 0.1.1 was tagged; the wheel and sdist attached to this release are unchanged by that, and these notes were corrected on 2026-11-06 to name 0.2.0 instead of git main.

What was NOT verified

No live OpenCode session has ever loaded this output. There were no OpenCode
credentials or model backend available while this was built, so the end-to-end
path stops at the MCP server: the configuration is schema-valid and its server
command works, but "OpenCode actually started, read .opencode/, and used the
skill and subagent" is unproven. A schema-valid configuration is not a loaded
one.

Also unproven: whether OpenCode rewrites file_example into its own tool-name
scheme, and how it renders a description containing non-ASCII text.

Note on the 0.1.0 release

Tag 0.1.0 points at 9c41040, whose README predates the requirements section.
It is left in place and untouched. Use 0.1.1.

License

Apache-2.0.

hermit-opencode 0.1.0

Choose a tag to compare

@argszero argszero released this 04 Nov 06:26

Convert a hermit adapter into an OpenCode configuration.

pip install git+https://github.com/argszero/hermit-opencode
hermit-opencode path/to/adapter --output out/

Which hermit this needs — read this before you run it

Hermit is needed only for the tool server. The context, skills and roles
parts are plain files OpenCode reads directly and work with any hermit.

The mcp entry this tool emits — hermit serve adapter — requires a hermit
that reads the .hermit/adapter.yaml + exports.yaml layout: git main, or
any release after 0.1.0.

hermit-harness 0.1.0 from PyPI cannot serve this output. Its manifest
reader wants adapter.yaml at the adapter root, the layout hermit replaced in
its own #41, and both the embedded copy and the source adapter use the newer
layout — so no path, flag or environment setting makes 0.1.0 serve it. Measured:
the emitted command exits 1 with

ValueError: Missing adapter.yaml in <output>/adapter

Use:

pip install "git+https://github.com/Infini-AI-Lab/hermit"

What was verified

  • The suite: 12 passed, no network, no hermit installed.
  • opencode.json validates against https://opencode.ai/config.json (Draft202012, schema vendored in the repository).
  • The emitted mcp command was run under hermit 604ecf0, from the output directory with cwd: ".": a real MCP initialize / tools/list / tools/call exchange over stdio returned count_words('one two three') -> {'count': 3} and appended to .opencode/audit/tool-calls.jsonl.
  • The requirement above is a measurement, not a claim: the same command was run against hermit-harness==0.1.0 from PyPI (fails, output above) and against hermit 604ecf0 (succeeds). A test pins the emitted command and the README's Requirements table to each other so they cannot drift apart.

What was NOT verified

No live OpenCode session has ever loaded this output. There were no OpenCode
credentials or model backend available while this was built, so the end-to-end
path stops at the MCP server: the configuration is schema-valid and its server
command works, but "OpenCode actually started, read .opencode/, and used the
skill and subagent" is unproven. A schema-valid configuration is not a loaded
one.

Also unproven: whether OpenCode rewrites file_example into its own tool-name
scheme, and how it renders a description containing non-ASCII text.

Note on this tag

Tag 0.1.0 points at 9c41040, whose README predates the requirement section
above — the tag was cut before the release/0.1.0 promise was measured. The
corrected README and the pinning test are on main at 18dc8f8; install from
main to get them. The code that emits the configuration is unchanged between
the two.

License

Apache-2.0.