Skip to content

cli-v0.10.0

Choose a tag to compare

@github-actions github-actions released this 13 Oct 09:11
· 220 commits to main since this release
7ec4fb9

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.v1 manifest 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.yaml runners are graphs of agent, operation,
    tool, ask and skill steps, 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 and runx registry install is the one install, runx connector use is the one connector setup, runx mcp is the one MCP server, and
    runx skill takes inputs as -i name=value or one --inputs document.

Added

  • runx connector list|inspect|use|revoke|import-mcp, the one place a
    connector's authority is set up. use binds 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. list shows each connector
    with its instances, profiles and grants, revoke removes one, and
    import-mcp pins 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
    and registry publish take 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/contracts is 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/ and skills/ serves
    its own connectors to the skills inside it, named by the namespace its
    plugin.json declares.
  • 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 carry act: and connectors declare the effect a 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's context) gives a run the
    caller's context, the current_context and historical_context entries an
    agent context envelope carries; it informs the run and its children and
    never grants authority. The client also states a run's act.
  • runx skill --run-id <id> (and the client's runId) 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's dialect and endpoint-url
    under runx 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. setup names a connector as the skill's
    connectors: block does, an id or a qualified ref such as runx/github, and
    a package's cases reach the connector versions the project has installed.
  • Skills: reddit account workflows, google-calendar reads,
    list-hygiene-judge, cold-outreach, github-pr-review, lead-qualify
    (which replaces lead-router), product-analytics, web-search,
    conversation-reply, conversation-review and attention-review, and the
    GitHub connector's issues.create.
  • Registry package metadata names the connectors a package declares and the
    operations it lists for each.
  • runx skill inspect records a registry ref its RUNX_REGISTRY_DIR does 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) once runx registry install has added it.
    runx connector inspect and runx connector use for 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_DIR and
    RUNX_REGISTRY_DIR, each relative to the workspace.
  • Approvals are addressed by the step that asks (<child>#<step> below the
    root). runx resume reads its answers from one document, on stdin or in a
    file the operator names, and writes them nowhere: .runx/continuations is
    gone.
  • Graph references read values, not artifact envelopes.
  • Receipt-tree grouping and the hosted notary's counter-seal check live in
    runx-receipts beside receipt verification, so the CLI and every host that
    links it verify alike; runx verify keeps 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.invocation schema by reference, and paid
    invocations carry attribution.
  • Contracts emit closed string enums as enum, and the x402 upstream is pinned
    to @x402/core 2.27.0.
  • runx skill -i name=value reads 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 export writes its invocation
    examples the same way.
  • The runtime states a run's status and outcome: a run waiting only on
    approvals is needs_approval, and every run output carries the outcome its
    closure gives. The CLI and @runxhq/client pass them through.
  • Every command that prints JSON reads -j as --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/client and 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_DIR resolves 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 named closure,
    the name its answer states how its act closed under.
  • A runner's inline harness.cases run 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.yaml execution profiles, and the runner source kinds cli-tool,
    javascript, mcp, external-adapter, thread-outbox and approval.
  • The graph-language fanout: groups, step retry:, charter_from and
    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 by max_fanout and max_child_depth, and the kernel retries effects
    within their declared tolerance.
  • runx data migrate, runx skill -p and --credential-profile, and
    runx login --from-gh. A credential's --auth-mode and --audience are
    gone too: a connector's manifest declares where its credential may be sent.
  • runx dev, its fixture lanes and the runx.dev.v1 report: a tool is
    proved through the skill that calls it, by runx harness. The
    runx.run-summary.v1 contract, which nothing produced, goes with them.
  • runx kernel eval and runx parser eval: they were the repository's
    development evaluators, and its scripts now build them as examples of
    runx-core and runx-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|configured selects what is
    trusted.
  • The --receipts spelling of --receipt-dir (-R stays).
  • runx add, runx registry read, runx registry resolve and the
    runx registry connector verbs. runx skill <ref> fetches the skill it
    runs, runx registry install adds a package without running it, and
    skill inspect and connector inspect show one. A repository's skills are
    published with runx registry publish.
  • runx credential set|list|remove, runx connect list|start|status|revoke
    and runx connector instances: runx connector use|list|revoke set up,
    show and remove every kind of connector authority.
  • runx history lists runs, filtered by --skill, --status, --since,
    --until and --limit, and inspects one when given its receipt id; its
    --source, --actor, --artifact-type, --include-harness and
    --include-internal flags are gone.
  • The built-in GitHub CLI driver, vendor reference kinds and vendor rules in
    the core; vendor behavior lives in connector manifests.
  • The nitrosend and sourcey skills and the nitrosend, ausca-browser
    and ausca-inbox connectors are no longer part of runx.
    conversation-reply replies through Slack.
  • The skill tree holds only runx-maintained packages.
    answer-from-docs, meeting-followup and incident-commander stay with
    their contributors. business-ops, chief-of-staff, governed-outbound and
    operator-inbox were facades over other skills and are retired.
    mock-charge, mock-pay and mock-refund are test fixtures, and
    reflect-digest, which nothing called, is deleted.
  • The external_receipt.verify tool and its
    runx.external_receipt.verification.v1 packet. A skill verifies a scafld
    receipt with the scafld/receipt.verify operation, which runs the scafld CLI
    on the host as a trusted host process; RUNX_SCAFLD_BIN is not read.

Security

  • A host's workspace policy (RUNX_HOSTED_WORKSPACE_POLICY_JSON) can refuse
    every trusted host process with refuseHostProcesses: 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 .env may not set Runx's own RUNX_ 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...> is runx mcp <skill-ref...>,
    and runx turn <run-id> is runx mcp --run <run-id>.
  • runx policy inspect|lint <policy.json> is runx policy <policy.json>;
    runx history <receipt-id> --detail is runx history <receipt-id>.
  • runx init is gone. A project is the nearest directory holding .git,
    skills/ or pnpm-workspace.yaml (or RUNX_CWD); .runx/project.json is
    not read, and the installation records its id on first use. runx new
    writes to skills/<name> by default, running skill-build exactly as
    runx skill would.
  • runx skill takes inputs one way per shape: -i name=value for each input,
    or the whole input object with --inputs file|-. --input-json and bare
    --name value inputs are gone, and a flag runx does not own is refused,
    never read as an input. --full-operator-context is --diagnostics, which
    shows everything, and the unused --run is gone.
  • runx config set public-token is gone: a runx account credential is stored
    by runx login, bound to its principal and API, and RUNX_PUBLIC_API_TOKEN
    supplies one to a single process.
  • runx publish <receipt.json> is runx notarize <receipt.json>: the hosted
    notary counter-seals the receipt and publishes the record, which anyone can
    read. runx verify --notary checks the counter-seal.
  • Skills: rename X.yaml to run.yaml and express each runner as a graph of
    the five step kinds. External calls become operation steps 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),
    --session or --hosted, or select an instance, profile or grant with
    runx connector use <connector> <name>. runx credential and
    runx connect are gone, and profiles bound by runx credential bind are
    not read.
  • Installing: runx add <ref> is runx registry install <ref>, and running
    a ref with runx skill fetches it. runx registry connector install|package|publish
    are runx registry install|package|publish. A version is named only in the
    ref, <ref>@<version>: install's --version and --to are gone, and
    registry publish --version stays as the published label. --registry-dir
    is gone; --registry takes a URL or a local registry directory.
  • Core skills are renamed: policy-author is policy-draft, audit-receipt
    is receipt-audit, ledger is receipt-query, adopt-skill is
    skill-adopt, skill-lab is skill-build and review-skill is
    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 subject kind is step or graph. The seal's free-text
    reason_code is replaced by an optional reason from a closed vocabulary,
    present only when the disposition alone does not say why. Receipts carry no
    unsigned metadata, and execution limits are not recorded on them.
  • Sessions: runx connector use <connector> --session pins 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 the connector
    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 sets max_fanout and max_child_depth on 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. The zapier and n8n connectors take their
    webhook URL as a credential (catch_hook, webhook), presented as the
    request URL with the new url placement, so it never enters a run's inputs,
    records or receipts. Bind it with runx connector use zapier --credential catch_hook (or n8n --credential webhook), the URL on stdin; zapier-handoff no
    longer takes zapier_account_id/zapier_hook_id, and n8n-handoff no
    longer takes workflow_slug.
  • run.yaml: the top-level emits and runx blocks and a runner's
    runx.post_run are refused; they were read and ignored. A step's
    artifacts refuses unknown keys. The catalog's runtime_path and
    requires_adapter are removed; nothing checked them.
  • Hosted artifacts: the artifact.allocate and artifact.handoff tools are
    gone. A skill stores a value with an operation step against the
    runx-maintained artifact connector, artifact/artifact.allocate, with
    purpose, media_type and one of value or data_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's provider_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 install reports the installed package's
    package_digest and, from a hosted registry, an acquisition with its
    publisher and install count; the untyped receipt_metadata map is gone.
  • runx registry publish --owner is --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 (or RUNX_HOSTED_API_ADMIN_TOKEN);
    RUNX_HOSTED_REGISTRY_PUBLISH_OWNER is not read.
  • Registry refs have one spelling, registry:<owner>/<name>[@<version>].
    runx-registry: and runx://skill/ are not registry refs, and registry
    links print the registry: form.
  • An input declared artifact takes 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.json with an
    x-runx-schema marker. Their runx.ai/spec/... and runx.ai/schemas/...
    ids are gone, as are RUNX_CONTROL_SCHEMA_REFS and
    RUNX_AUXILIARY_SCHEMA_IDS in @runxhq/contracts; use RUNX_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 under runx/ when first used. The
    home's official-skills and registry-skills caches, the project's
    .runx/registry-step-skills, the home connectors/ package cache,
    RUNX_OFFICIAL_SKILLS_DIR and runx init --prefetch are gone.
  • "Official" is gone from connector and skill names: runx maintains its
    adapters, and only a vendor's own publication is the vendor's.
    officialConnectors is runxMaintainedConnectors; the locks are
    skills/runx-maintained.lock.json and
    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.v1 is closed: besides its identity, status and result it
    carries only skill_name, runner, closure, error, refusal,
    context, trace, next and entry_provenance. next appears only when
    the run is paused.
  • RUNX_AGENT_PROVIDER selects a built-in profile or a provider configured by
    dialect and endpoint; ANTHROPIC_API_KEY, OPENAI_API_KEY or
    GEMINI_API_KEY supplies the key.

Upgrade guidance

  • Install with npm install --global @runxhq/cli@0.10.0, Homebrew, Scoop, or
    the matching release archive, then confirm runx --version reports
    runx-cli 0.10.0.
  • Rebind credentials with runx connector use <connector> --credential <name>
    (or --session, or --hosted for a runx Connect grant), then check each
    connector with runx connector inspect <connector>.
  • Convert skills to run.yaml and run runx harness <skill-dir> before
    publishing; runx skill inspect shows 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/keys as writable, restrict it with chmod 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