Repository navigation
cli-v0.10.0
·
220 commits
to main
since this release
Runx CLI 0.10.0
Runx 0.10.0 rebuilds the core around connectors. Every external read and write
is a declared connector operation, run under an instance the operator bound,
admitted against its grant and approval, confirmed by its own readback where
the provider can be read, and sealed in a receipt that states only what was
declared or observed. Skills are graphs of five step kinds in run.yaml, and a
runner with no steps is one agent turn the attached agent works by calling back
into the run. This release breaks the 0.9 skill, credential and receipt
contracts; read the breaking changes before upgrading.
Highlights
- Connectors: a
runx.connector.v1manifest declares each operation's request,
credentials, approval, effect and readback. The kernel admits the call,
performs it once, reads it back and seals it; no skill holds a credential. - One skill format:
run.yamlrunners are graphs ofagent,operation,
tool,askandskillsteps, with one reference syntax for inputs, step
results and acts. - Agent turns: a runner with no steps is one turn. The agent's calls into the
run (operations, tools, asks, skills) are each admitted and recorded, and an
open turn can be served as MCP tools. - Receipts state only what their issuer declared or observed, carry typed
observations, and are signed by the runx home's own local identity unless a
hosted or CI signer is configured. - The managed agent speaks the Anthropic Messages and Chat Completions
dialects, with built-in Anthropic, OpenAI and Gemini profiles. - One way to do each thing: 0.9's 24 top-level commands become 17. Running a ref
fetches it andrunx registry installis the one install,runx connector useis the one connector setup,runx mcpis the one MCP server, and
runx skilltakes inputs as-i name=valueor one--inputsdocument.
Added
runx connector list|inspect|use|revoke|import-mcp, the one place a
connector's authority is set up.usebinds an instance, profile or grant
confirmed earlier, the signed-in local session (--session), a local secret
read from stdin (--credential <name>), or a new runx Connect grant
(--hosted, which prints the authorization link and waits for it); with
nothing named it takes the one available path.listshows each connector
with its instances, profiles and grants,revokeremoves one, and
import-mcppins the tools an MCP server serves.runx registry install <publisher>/<name>[@version]adds a skill or a
connector by name; a skill brings the connectors it binds.registry package
andregistry publishtake a skill or a connector and read the kind from the
path.@runxhq/client, the client hosts drive runx through, is published to npm
with each release, and@runxhq/contractsis released with it.- Connector implementations over declared HTTP requests (with readbacks,
paging, rate-limit halts and repeated writes), MCP over HTTP or stdio,
process tools and data stores (store: SQLite, PostgreSQL, Redis). - An HTTP implementation presents a credential as the request URL
({type: url, field: url}, for a webhook) or at a JSON pointer in the
request body ({type: body, field: key, pointer: /key}, for a provider such
as IndexNow that reads its key there). A body credential needs every request
to declare a literal JSON object holding the pointer's parent and never
setting it, and is presented on local placements only. Either value is
redacted wherever it would be echoed. - Plugin repositories: a directory holding
connectors/andskills/serves
its own connectors to the skills inside it, named by the namespace its
plugin.jsondeclares. - Connectors are named
<publisher>/<id>. Instances, hosted grants, credential
profiles and receipts bind the qualified connector with its manifest and
connector digests, and a receipt's act seals the connector operation it ran. runx skill --act <json>states the act a run is invoked with; operation
steps carryact:and connectors declare theeffecta write makes.runx mcp --run <run-id>serves the agent turns a paused run waits on as
MCP tools over stdio, scoped to that run alone.runx mcp <skill-ref...>
serves the same turn tools beside its skills, over the runs its own skill
calls open and no other.runx skill --context <json>(and the client'scontext) gives a run the
caller's context, thecurrent_contextandhistorical_contextentries an
agent context envelope carries; it informs the run and its children and
never grants authority. The client also states a run'sact.runx skill --run-id <id>(and the client'srunId) pins a run's
submission identity: submitting it again continues that run, and a sealed
run returns what it sealed, so a host's retry never runs a step twice.runx config unset, and the managed agent'sdialectandendpoint-url
underrunx config set.- Harness cases bind connector credentials and sessions in
setup, answer a
request declared more than once in declared order, and fail when a declared
exchange is never requested.setupnames a connector as the skill's
connectors:block does, an id or a qualified ref such asrunx/github, and
a package's cases reach the connector versions the project has installed. - Skills:
redditaccount workflows,google-calendarreads,
list-hygiene-judge,cold-outreach,github-pr-review,lead-qualify
(which replaceslead-router),product-analytics,web-search,
conversation-reply,conversation-reviewandattention-review, and the
GitHub connector'sissues.create. - Registry package metadata names the connectors a package declares and the
operations it lists for each. runx skill inspectrecords a registry ref itsRUNX_REGISTRY_DIRdoes not
hold as an unresolved edge, so a host can supply those skills and inspect
again.- Publishing to a hosted registry binds the skills other publishers own that a
package composes: each registry ref the package names is read, as the
registry signed it, from the registry the package is published to, into a
registry directory of that publish's own.
Changed
- Only the runtime capability connectors (
store,web,vault,
artifact) ship inside runx. Every other runx-maintained connector is a
published package, like any skill outside the core: a published skill
carries the connectors it binds, and a local skill names one by its
publisher (runx/github) oncerunx registry installhas added it.
runx connector inspectandrunx connector usefor such a connector need
it installed first. - One protected kernel store per project holds runs, instances, custody and
usage. Every runx location resolves in one place, from the workspace
(RUNX_CWD),RUNX_HOME,RUNX_PROJECT_DIR,RUNX_RECEIPT_DIRand
RUNX_REGISTRY_DIR, each relative to the workspace. - Approvals are addressed by the step that asks (
<child>#<step>below the
root).runx resumereads its answers from one document, on stdin or in a
file the operator names, and writes them nowhere:.runx/continuationsis
gone. - Graph references read values, not artifact envelopes.
- Receipt-tree grouping and the hosted notary's counter-seal check live in
runx-receiptsbeside receipt verification, so the CLI and every host that
links it verify alike;runx verifykeeps its surface. - A skill package is validated, and a packet schema parsed, once per exact
source in a process, so a run no longer re-parses them at every step. - x402 advertises the
runx.invocationschema by reference, and paid
invocations carry attribution. - Contracts emit closed string enums as
enum, and the x402 upstream is pinned
to@x402/core2.27.0. runx skill -i name=valuereads each value by the type its runner declares
for that input (a string as written, any other type as JSON), and refuses an
input the runner does not declare.runx exportwrites its invocation
examples the same way.- The runtime states a run's
statusandoutcome: a run waiting only on
approvals isneeds_approval, and every run output carries the outcome its
closure gives. The CLI and@runxhq/clientpass them through. - Every command that prints JSON reads
-jas--json. - Graph steps and agent turn calls share one crash model: a step or call that
reaches the world (an operation, a native tool, a trusted host process) is
claimed in the run's record before it runs. One that never settled, because
its driver stopped, holds the run on a retry request, answered with
{"retry": true}, instead of running again unseen; a second driver of the
same run is refused before anything runs. Worker compute runs again. - Every verifier of a receipt tree (
runx verify, the receipt proof, the
standalone verifier,@runxhq/clientand the hosted archive) applies one
rule: each receipt committed once by its parent, at most 1024 receipts and 64
levels below the root. A receipt two parents commit is refused. RUNX_REGISTRY_DIRresolves against the workspace for every reader.- A paged HTTP read is finite whatever its call asks: it stops at 100 pages,
10,000 items, 32 MiB or two minutes and returns the provider's next cursor
with what it read. - An agent turn is addressed by the step that asks it, as an approval is by
its gate:<step>at the root and<path>#<step>in a child run, in resume
files,runx mcp --run, harness answers and turn scripts. Two steps that share a
task are two turns. An agent step may not declare an output namedclosure,
the name its answer states how its act closed under. - A runner's inline
harness.casesrun through the same harness engine as
fixtures/*.yaml: each seals under the public fixture key whatever signer is
configured, and is held to the same expectations.
Fixed
- A declared request whose optional query values are all absent no longer
ends its URL in a bare?. - Pinned registry version reads are isolated from other versions.
- The vendor presentation is kept out of the payment quote fingerprint.
- Suspended run outcomes survive a resume, and plugin connectors bind from the
directory runx was invoked in. - A missing connector error names where it was looked for.
Removed
X.yamlexecution profiles, and the runner source kindscli-tool,
javascript,mcp,external-adapter,thread-outboxandapproval.- The graph-language
fanout:groups, stepretry:,charter_fromand
mint. Fan-out and retry now belong to the driving agent and the host: the
agent fans out inside its turn by calling the child skills in its allowance,
bounded bymax_fanoutandmax_child_depth, and the kernel retries effects
within their declared tolerance. runx data migrate,runx skill -pand--credential-profile, and
runx login --from-gh. A credential's--auth-modeand--audienceare
gone too: a connector's manifest declares where its credential may be sent.runx dev, its fixture lanes and therunx.dev.v1report: a tool is
proved through the skill that calls it, byrunx harness. The
runx.run-summary.v1contract, which nothing produced, goes with them.runx kernel evalandrunx parser eval: they were the repository's
development evaluators, and its scripts now build them as examples of
runx-coreandrunx-parser. The CLI ships no development tool.runx verify --allow-local-development-signatures: a local receipt verifies
against the home's own key, and--trust home|configuredselects what is
trusted.- The
--receiptsspelling of--receipt-dir(-Rstays). runx add,runx registry read,runx registry resolveand the
runx registry connectorverbs.runx skill <ref>fetches the skill it
runs,runx registry installadds a package without running it, and
skill inspectandconnector inspectshow one. A repository's skills are
published withrunx registry publish.runx credential set|list|remove,runx connect list|start|status|revoke
andrunx connector instances:runx connector use|list|revokeset up,
show and remove every kind of connector authority.runx historylists runs, filtered by--skill,--status,--since,
--untiland--limit, and inspects one when given its receipt id; its
--source,--actor,--artifact-type,--include-harnessand
--include-internalflags are gone.- The built-in GitHub CLI driver, vendor reference kinds and vendor rules in
the core; vendor behavior lives in connector manifests. - The
nitrosendandsourceyskills and thenitrosend,ausca-browser
andausca-inboxconnectors are no longer part of runx.
conversation-replyreplies through Slack. - The skill tree holds only runx-maintained packages.
answer-from-docs,meeting-followupandincident-commanderstay with
their contributors.business-ops,chief-of-staff,governed-outboundand
operator-inboxwere facades over other skills and are retired.
mock-charge,mock-payandmock-refundare test fixtures, and
reflect-digest, which nothing called, is deleted. - The
external_receipt.verifytool and its
runx.external_receipt.verification.v1packet. A skill verifies a scafld
receipt with thescafld/receipt.verifyoperation, which runs the scafld CLI
on the host as a trusted host process;RUNX_SCAFLD_BINis not read.
Security
- A host's workspace policy (
RUNX_HOSTED_WORKSPACE_POLICY_JSON) can refuse
every trusted host process withrefuseHostProcesses: process tools,
connector process tools and stdio MCP servers. A harness case's own
environment cannot change the host's policy. runx Cloud sets it for every
publication harness and hosted run. - A skill package is read within its 20 MiB admission budget, so an oversized
file is refused without being loaded whole. - Credentials are delivered only to the operation that admits them, scrubbed
from refusal and provider answers, and tracked per field for multi-field
secrets. A process tool receives its credential only in the variable its
manifest names. - Local receipts are signed by a key unique to each runx home instead of a
shared fixture key, and the hosted demo key is named by the id it derives. - Harness cases run in their own home and project with ambient grants and
connector credentials removed, and never reach the network. - A workspace
.envmay not set Runx's ownRUNX_variables, so a cloned
repository cannot redirect Runx's state, Connect or signing, or supply host
authority. - A stdio MCP server, a process the runtime starts with the instance's
credential, is sealed as a trusted host process rather than a native
capability. - The JavaScript worker keeps local time at UTC, so a skill's compute reads
nothing of the host, its time zone included. - The home's config secret and sealed config values are kept like the local
receipt key: created closed to other users, never written open, and read only
from a key directory this user owns that no one else can write. Where a
platform gives runx no owner-only protection it can check, no local secret is
stored or read.
Breaking changes
- One MCP server:
runx mcp serve <skill-ref...>isrunx mcp <skill-ref...>,
andrunx turn <run-id>isrunx mcp --run <run-id>. runx policy inspect|lint <policy.json>isrunx policy <policy.json>;
runx history <receipt-id> --detailisrunx history <receipt-id>.runx initis gone. A project is the nearest directory holding.git,
skills/orpnpm-workspace.yaml(orRUNX_CWD);.runx/project.jsonis
not read, and the installation records its id on first use.runx new
writes toskills/<name>by default, running skill-build exactly as
runx skillwould.runx skilltakes inputs one way per shape:-i name=valuefor each input,
or the whole input object with--inputs file|-.--input-jsonand bare
--name valueinputs are gone, and a flag runx does not own is refused,
never read as an input.--full-operator-contextis--diagnostics, which
shows everything, and the unused--runis gone.runx config set public-tokenis gone: a runx account credential is stored
byrunx login, bound to its principal and API, andRUNX_PUBLIC_API_TOKEN
supplies one to a single process.runx publish <receipt.json>isrunx notarize <receipt.json>: the hosted
notary counter-seals the receipt and publishes the record, which anyone can
read.runx verify --notarychecks the counter-seal.- Skills: rename
X.yamltorun.yamland express each runner as a graph of
the five step kinds. External calls becomeoperationsteps against a
connector; removed runner kinds have no compatibility path. - Credentials and grants: bind a connector with
runx connector use <connector> --credential <name>(the secret on stdin),
--sessionor--hosted, or select an instance, profile or grant with
runx connector use <connector> <name>.runx credentialand
runx connectare gone, and profiles bound byrunx credential bindare
not read. - Installing:
runx add <ref>isrunx registry install <ref>, and running
a ref withrunx skillfetches it.runx registry connector install|package|publish
arerunx registry install|package|publish. A version is named only in the
ref,<ref>@<version>: install's--versionand--toare gone, and
registry publish --versionstays as the published label.--registry-dir
is gone;--registrytakes a URL or a local registry directory. - Core skills are renamed:
policy-authorispolicy-draft,audit-receipt
isreceipt-audit,ledgerisreceipt-query,adopt-skillis
skill-adopt,skill-labisskill-buildandreview-skillis
skill-review. - Plugins: declare the plugin's namespace in
plugin.json
({"namespace": "<publisher>"}); a plugin without one does not load its
connectors. Confirm each connector instance again after upgrading, since
instances now bind the qualified connector and its digests. - Receipts: the 0.9 shapes are not produced. Act and decision fields appear
only when stated, and local receipts verify against the home's own key. A
receipt's subjectkindissteporgraph. The seal's free-text
reason_codeis replaced by an optionalreasonfrom a closed vocabulary,
present only when the disposition alone does not say why. Receipts carry no
unsignedmetadata, and execution limits are not recorded on them. - Sessions:
runx connector use <connector> --sessionpins the scopes the
session may serve, every scope its credential serves unless--scope
narrows it; confirm sessions again after upgrading. A local instance's
receipts name that instance, not a grant, as the capability that admitted
the call. - Authority: a term bounds only what admission enforces: connector
operations, grant scopes, targets and use limits, on theconnector
family. Conditions, capabilities, effect limits and the domain list bounds
are removed. A term that names no expiry expires with its earliest parent.
A host setsmax_fanoutandmax_child_depthon the run's authority, not
on a delegation. - Connectors: an approval alone never authorizes a write. A connector that
writes to a provider declares a credential, a session or a grant; one with no
authentication may only read. Thezapierandn8nconnectors take their
webhook URL as a credential (catch_hook,webhook), presented as the
request URL with the newurlplacement, so it never enters a run's inputs,
records or receipts. Bind it withrunx connector use zapier --credential catch_hook(orn8n --credential webhook), the URL on stdin;zapier-handoffno
longer takeszapier_account_id/zapier_hook_id, andn8n-handoffno
longer takesworkflow_slug. run.yaml: the top-levelemitsandrunxblocks and a runner's
runx.post_runare refused; they were read and ignored. A step's
artifactsrefuses unknown keys. The catalog'sruntime_pathand
requires_adapterare removed; nothing checked them.- Hosted artifacts: the
artifact.allocateandartifact.handofftools are
gone. A skill stores a value with anoperationstep against the
runx-maintainedartifactconnector,artifact/artifact.allocate, with
purpose,media_typeand one ofvalueordata_base64; the call is
admitted and read back like any operation, keyed by the step's
idempotency_key, and stored for the runx account the runtime is signed in
as. Its result is the step'sprovider_operation.result. Handing an
artifact to another principal is a hosted API call, not a runtime tool. - Paid job authority:
RUNX_PROVIDER_PERMISSION_PAID_EXTERNAL_JOB_AUTHORITY_JSON
is not read, and a paid job no longer stands in for an approval: an
operation that needs one is approved by a person. runx registry installreports the installed package's
package_digestand, from a hosted registry, anacquisitionwith its
publisher and install count; the untypedreceipt_metadatamap is gone.runx registry publish --owneris--publisher, the namespace a skill is
published into, for a principal that may publish into several, an operator's
publish and a local registry alike. An operator publish is the one made with
RUNX_HOSTED_REGISTRY_PUBLISH_TOKEN(orRUNX_HOSTED_API_ADMIN_TOKEN);
RUNX_HOSTED_REGISTRY_PUBLISH_OWNERis not read.- Registry refs have one spelling,
registry:<owner>/<name>[@<version>].
runx-registry:andrunx://skill/are not registry refs, and registry
links print theregistry:form. - An input declared
artifacttakes exactly the artifact envelope a step
emits,{schema?, data}. - A process tool answers with JSON on stdout, or nothing. Other stdout fails
the invocation instead of becoming a string value. - The host-protocol and auxiliary contracts (
output,agent-context-envelope,
resolution-request,resolution-response,question,approval-gate,
agent-act-invocation,act-result,turn-call,turn-status,
registry-binding,review-receipt-output) are identified like every other
contract:https://schemas.runx.ai/runx/<name>/v1.jsonwith an
x-runx-schemamarker. Theirrunx.ai/spec/...andrunx.ai/schemas/...
ids are gone, as areRUNX_CONTROL_SCHEMA_REFSand
RUNX_AUXILIARY_SCHEMA_IDSin@runxhq/contracts; useRUNX_CONTRACT_IDS. - A project keeps every package it runs in its own
skills/and
connectors/: the user's own, every package added from a registry (by
runx registry install, a registry ref or a registry step's child) at
<publisher>/<name>/<version>/, and the core skills and runtime capability
connectors the release carries, added underrunx/when first used. The
home'sofficial-skillsandregistry-skillscaches, the project's
.runx/registry-step-skills, the homeconnectors/package cache,
RUNX_OFFICIAL_SKILLS_DIRandrunx init --prefetchare gone. - "Official" is gone from connector and skill names: runx maintains its
adapters, and only a vendor's own publication is the vendor's.
officialConnectorsisrunxMaintainedConnectors; the locks are
skills/runx-maintained.lock.jsonand
registry/runx-maintained-connectors.lock.json. - Approvals and answers keyed by request ids from 0.9 runs do not resume on
0.10. runx.skill_run.v1is closed: besides its identity, status and result it
carries onlyskill_name,runner,closure,error,refusal,
context,trace,nextandentry_provenance.nextappears only when
the run is paused.RUNX_AGENT_PROVIDERselects a built-in profile or a provider configured by
dialect and endpoint;ANTHROPIC_API_KEY,OPENAI_API_KEYor
GEMINI_API_KEYsupplies the key.
Upgrade guidance
- Install with
npm install --global @runxhq/cli@0.10.0, Homebrew, Scoop, or
the matching release archive, then confirmrunx --versionreports
runx-cli 0.10.0. - Rebind credentials with
runx connector use <connector> --credential <name>
(or--session, or--hostedfor a runx Connect grant), then check each
connector withrunx connector inspect <connector>. - Convert skills to
run.yamland runrunx harness <skill-dir>before
publishing;runx skill inspectshows how a runner resolves. - Finish runs paused under 0.9 before upgrading: 0.10 does not resume them.
- Local signing refuses a keys directory other users can write. If
runx
names~/.runx/keysas writable, restrict it withchmod 700 ~/.runx/keys.
Contributors
This release was built by the runx maintainers. Thanks to everyone who
reported issues against 0.9.
Full changelog:
cli-v0.9.1...cli-v0.10.0