Repository navigation
Releases
v0.5.3
The Qwen Code install command, which was wrong in a way that only showed up when something installed it for you.
\qwen extensions install https://github.com/iamvazghen/jevqueue\ asks which plugin to install, so the command as written needed a human at the keyboard. Naming the plugin and passing --consent\ installs it outright:
\\�ash
qwen extensions install iamvazghen/jevqueue:jevqueue --consent
\\
The Gemini command was missing --consent\ for the same reason.
v0.5.2
Register the MCP server the awareness document tells agents to call.
\claude mcp list\ showed no jevqueue server. The plugin shipped \mcp/jevqueue_mcp.py\ and the awareness document told every agent to call \jevqueue_decide\ -- but no manifest declared the server, so the tool did not exist.
Claude Code, Codex and GitHub Copilot now declare it. \�in/jevqueue-mcp.mjs\ finds a Python interpreter (python3, python or py -3, whichever is actually there) and hands the process over with stdio inherited. Codex gets its own configuration file, because its legacy plugin parser does not expand placeholders in MCP arguments.
Tests: 368, offline.
v0.5.1
0.5.1 — the distribution stops pretending to be on PyPI
The README carried PyPI badges and pip install jevqueue; five documentation pages and
three adapter error messages carried the same command. Nothing was ever published, so
every one of those commands failed at the install step.
The install now names the repository:
pip install "jevqueue @ git+https://github.com/iamvazghen/jevqueue.git"The license statement is precise. MIT covers everything in this repository — the
decision layer, the gate, the hook scripts, the manifests, the skills, the MCP server and
the documentation. No third-party code is vendored, and there are no required dependencies.
The hosted Jev model is a separately hosted service under TypeSafe's terms; it is not
distributed here, and the offline rules baseline that is here is covered by MIT.
Two more fixes in the same pass. The GitHub Copilot manifest said 0.4.0 and the
Gemini extension said 0.3.0 while everything else said 0.5.0 — a test holds them to
the package version now. And docs/index.md was a stale copy of the README that nothing
referenced; it is gone, and the site generator refuses to let it come back.
Full detail in the changelog.
jevqueue 0.5.0: explain the plugin to the agent that is using it
A plugin whose only artefact is a README has already failed. The agent does not read READMEs -- it reads what is in its context.
The awareness document. A \SessionStart\ hook (Claude Code, Codex) and a \BeforeAgent\ hook (Gemini) now inject a short document into the session: what the queue is, when to ask it, what to do when it says no, and why it costs no generated tokens. It is short on purpose -- it is paid for in every conversation, including the ones where the queue has nothing to do.
The docs the site was missing. \docs/install.md\ covers installing, enabling, testing and how it gets used, for every agent in the matrix. \docs/benefits.md\ is for the owner of the agent rather than the agent itself: the control-flow problem being solved, what changes, what it costs, and what it saves.
The token numbers are measured, not asserted. On the benchmark's eight-tool corpus:
| Input | Output | |
|---|---|---|
| A generative router choosing a tool | ~674 (schemas + state) | the reasoning tokens to emit a name |
| The decision layer | 215 (state only) | 0 |
| A step served from \static_tools\ | -- | 0 -- no model is called |
The 460-token gap is the tool schemas: a generative router has to receive every tool definition to choose between them, while the decision layer scores criteria against them so they never enter the context. That gap grows with the size of the toolset.
357 tests, offline.
jevqueue 0.4.0: a plugin for the CLI agent ecosystem
The plugin stops being a Claude Code plugin and starts being a plugin for the CLI agent ecosystem.
Gemini CLI / Qwen Code — a real extension: the MCP server, the skills, and a \BeforeTool\ hook in Gemini's dialect. Verified to install.
opencode — a plugin, because opencode has no hook configuration file and a plugin is the hook. \ ool.execute.before, throwing to refuse the call.
Cursor, Windsurf, Kiro, Cline, OpenClaw, GitHub Copilot, agents.md — a rules file each, all generated from one body so the guidance cannot drift between agents.
Two hook dialects, two files. Claude Code and Codex speak \PreToolUse; Gemini speaks \BeforeTool; the same gate script answers both by looking at the event name it is handed. Gemini insists on \hooks/hooks.json, which is the path Claude Code reads, so the dialects are kept apart and Claude Code reports one harmless warning for the event it finds and ignores.
The floor learned every runtime's shell tool. \Bash,
un_shell_command, \�ash,
un_terminal_cmd\ and the rest. A floor that only knew one agent's tool name was a floor that only worked in one agent.
343 tests, offline. CI now validates against both ecosystems.
jevqueue 0.3.0: one project, one install
One project, one install
The decision layer and the plugin are the same package now.
pip install jevqueue # no dependenciesThere is no separate library to install alongside the plugin, and no setup step. The judgment
model, the typed questions, the distrust layer, the guard order, the state projection, the
offline baseline and the five framework adapters are all in jevqueue/, and the plugin surface
-- hooks, commands, skills, the MCP server, the command line -- sits on top of it.
The package has no required dependencies
The offline decision layer is pure standard library. httpx is needed only for the hosted
model, and it is an extra:
pip install "jevqueue[hosted]"A plugin that needs an install step before it works is a plugin people do not install.
The floor is now a floor, not a fallback
The catastrophic-operation list used to run only when the decision layer was unavailable,
which meant a real model could overrule it -- a decision layer that shrugged at rm -rf /
would have been allowed to.
It is consulted before the decision layer now, always. And it is also what stands in when
the decision layer cannot be reached, which is exactly when you want it.
Same list. Different place in the order.
Two different things, two different names
The library's Decision (an action, a confidence, a risk) and the plugin's verdict (allow or
refuse, with a reason) are different things with different jobs, and giving them the same name
invited confusion. The hook engine is jevqueue/gate.py and the floor is
jevqueue/policy.py.
The benchmark came across too
It is the best artefact in the project, so it did not stay behind. bench/ holds the labelled
corpus, the runner and a published result, with a test that fails if the code drifts away
from the published numbers.
routing accuracy 100.0% (70/70)
enforced rate 71.4% (50/70)
decision_ms p50/p95 0.395 / 0.496
What a plugin user does now
Nothing. Install it and the decision layer is already there. /jevqueue:setup no longer
installs anything: it checks the installation, walks through the two settings, and runs a
self-test that proves the queue refuses what it should.
claude plugin marketplace add iamvazghen/jevqueue
claude plugin install jevqueue@jevqueue258 tests, offline: no network, no API key, no provider.
jevqueue 0.2.0: installable by anyone, in Claude Code and Codex
Installable by anyone, in both ecosystems
# Claude Code
claude plugin marketplace add iamvazghen/jevqueue
claude plugin install jevqueue@jevqueue
# Codex CLI
codex plugin marketplace add iamvazghen/jevqueue
codex plugin add jevqueue@jevqueueBoth verified end to end against this repository. Claude Code also takes the one-command form
(claude plugin install jevqueue --marketplace iamvazghen/jevqueue, v2.1.292+) and the
in-session form (/plugin install jevqueue --marketplace iamvazghen/jevqueue, v2.1.275+).
The skills work in any agent that reads SKILL.md, and the MCP server works in any
MCP-capable agent — neither needs hooks.
The credential comes from the plugin's settings, and nowhere else
It used to fall back to TYPESAFE_API_KEY in the environment, which meant the plugin could
pick up a secret already sitting in your shell and ship it to a server. It now reads one
place: the typesafe_api_key setting in /config, marked sensitive. A test pins it, and a
second test walks the source to make sure no file names a credential environment variable at
all.
It says what it does with your data
PRIVACY.md is new, and it
is specific rather than reassuring: the two scripts that run, what is read, what is sent and
where, that the transcript is sent in full within the bound rather than summarised locally
first, that there is no fetch of any kind, no telemetry and no update check, and the one
small cached file that gets written. The only outbound request the plugin can ever make goes
to https://api.typesafe.ai/v1/systemone, and only when you have configured a key.
NOTICE carries the
attribution: jev-governor is MIT and by the same author, and Jev is a separately hosted
service whose terms apply when a key is configured.
Versions are pinned
/jevqueue:setup installs jev-governor==0.2.0, with a tagged git source as the fallback for
when it is not on PyPI yet. An unpinned install means the plugin's behaviour can change
underneath a user's feet without the plugin changing at all.
Other changes
.gitattributesis scoped to the one file that genuinely needs it (bin/jevqueue, which
breaks on a CRLF checkout), rather than rewriting line endings across the whole repository.- CI validates with
--strict, which is the mode the publish guidance asks for: a manifest
that passes loosely and fails strictly breaks somebody's install. - The README documents the minimum Claude Code version for each install form, because a
plugin that only installs on the newest release is not publicly available in any meaningful
sense.
40 tests, offline: no network, no API key, no provider.