Skip to content

Quest CLI 0.11.0

Latest

Choose a tag to compare

@jeremy-newhouse jeremy-newhouse released this 27 Sep 18:57
· 64 commits to dev since this release
eb1d9f4

The first release under constitution Article 3 (opum-ai/opum-agent
docs/reference/opum-project-constitution.md, ratified 2026-09-27): quest and
lore ship as a pair at one version number. lore 0.11.0 skips 0.10.0 to meet
it. Both are staged under the release-candidate dist-tag and qualified
together by opum-cli-e2e from registry installs. Only then does latest
move, quest first. It is minor rather than patch for two reasons. quest init
and quest agents gain opum-quest plugin detection and update. And a bare
quest agents --check in a Claude-only or Gemini-only project now exits 6
where it used to exit 0 (QCLI-373, below). Nothing else changed in any
command, flag or envelope.

Added

  • quest init and quest agents detect the opum-quest marketplace plugin
    (QCLI-371, with QCLI-378 to QCLI-384 closing parity with lore-cli). When the
    Claude or Codex target is selected, they read claude plugin list --json or
    codex plugin list --json and report the plugin as installed, disabled, not
    installed or not detectable, with a remedy. Neither ever installs or enables
    it. quest agents --update-instructions with an explicit --target updates
    an installed plugin and converges on the marketplace, and the skill is drawn
    from the marketplace source so the two copies cannot drift apart. The rules
    match lore-cli's:
    • Claude scopes rank managed > local > project > user > synced. Between two
      rows of one scope, the deeper projectPath decides (QCLI-379). A managed
      row decides and is never updated (QCLI-381).
    • A scope that cannot be named as a plain token gets no command at all:
      the update is reported not run, and the remedy is prose (QCLI-383). A
      token must start with a letter or digit (QCLI-382).
    • Every not-run report carries an updateDetail, and the Codex wording
      follows how far the update got (QCLI-384).
    • Runtime text is stripped of ANSI, control and bidi/invisible format
      characters before any output mode. --scope reaches a remedy or an
      argv only as a plain token. Plugin output is read up to 1 MiB (QCLI-380,
      QCLI-382).
    • The list deadline (15s) ends the runtime's whole process group, so a
      grandchild holding the pipes cannot keep quest alive (QCLI-378).
      QUEST_AGENT_PLUGINS_TIMEOUT_MS and QUEST_AGENT_PLUGINS_UPDATE_TIMEOUT_MS
      override the list and per-step update deadlines.

Changed

  • A bare quest agents --check no longer reports on the wrong file
    (QCLI-373). With no --target it still checks the Codex block, because the
    Codex managed block tells CI to run it that way. But in a project whose
    Quest block lives only in CLAUDE.md or GEMINI.md, it now exits 6 and
    names the --target to use, instead of exiting 0 about an AGENTS.md that
    was never the point.

  • Publishing refuses without an opum-cli-e2e qualification receipt, and
    publishes the qualified bytes
    (QCLI-366, QCLI-368). The publisher reads
    receipts/quest/<version>.json from opum-cli-e2e's main and refuses,
    dry run included, unless it binds this version, commit, qualification run
    and all seven candidate-bundle tarballs. The seven bundle tarballs are then
    published byte for byte instead of a repack of the working tree. After
    publishing, npm's dist.integrity must match every bundle file.
    .gitattributes pins the platform packages' LICENSE and package.json to LF,
    which the Windows runners' checkout had turned into CRLF. Release tooling
    only.

  • Publishing refuses unless lore is at the same version (QCLI-386,
    constitution Article 3 clause 6). Both publishers read @opum-ai/lore's
    package.json on opum-ai/lore-cli's main, dry run included, and refuse
    on a mismatch or on any failure to read it.
    scripts/qualification/version-parity.mjs --require runs the same check on
    its own. Release tooling only.

  • A release is staged under the release-candidate dist-tag, and latest
    moves in a separate step
    (QCLI-385, constitution Article 3 clause 5). Both
    publishers now pass --tag release-candidate on every npm publish, so
    publishing leaves latest where it was. scripts/promote-release.mjs moves
    latest after opum-cli-e2e has qualified the staged lore/quest pair from
    registry installs. It refuses unless all seven packages are staged at the
    version, and it records every prior latest before moving any tag. It moves
    the platform packages first and the wrapper last. A failure part way through
    restores the tags that run moved, and --rollback <record> restores all of
    them. Release tooling only; no command, flag, envelope or exit code of
    quest changed.

  • Moving latest requires opum-cli-e2e's verdict on the staged pair
    (QCLI-388). scripts/promote-release.mjs reads
    receipts/pair/<version>.json from opum-cli-e2e's main and refuses unless
    it is QUALIFIED, names quest and lore at the same version, and was taken
    from registry installs. Every recorded distIntegrity must also match what
    npm serves when the promotion runs. A missing or unreadable receipt refuses.
    Rolling back is never gated. Release tooling only.

Fixed

  • task edit --if-revision reports a stale edit as a conflict (QCLI-374).
    A stale revision is now refused with exit 5 before the patch is folded. A
    concurrent removal of the same value used to surface as an exit-6
    validation miss rather than the conflict it is. Callers that retry on exit
    5 now retry.
  • scripts/publish-release.mjs no longer reports a locked Keychain entry as
    a missing token
    (QCLI-349). It used to treat every security failure the
    same way and print "no stored token found", which points at the wrong fix. A
    non-interactive read that fails with exit 36 (errSecInteractionNotAllowed)
    now says the entry exists and names security unlock-keychain. Exit 44 still
    says to create and store a token. Any other failure is reported as "could not
    be checked". A real publish with the entry locked and no --otp refuses with
    the unlock remedy. This is release tooling only; no command, flag, envelope
    or exit code of quest changed.
  • The publisher's success line names what it actually verified (QCLI-350).
    "@opum-ai/quest published and verified (N checks)" described
    checks of the six platform packages against the receipt, not of the
    wrapper. On 0.9.0 it printed while an anonymous read of the wrapper still
    returned 404. The script now checks that the wrapper resolves for a consumer,
    using the same read that gates the platform packages, before it prints
    anything. The line then lists each object with the check that verified it.
    A package the registry does not show yet is described as one of three
    states (slow, staged, never landed) instead of two. The wrapper is still
    withheld whenever any platform package does not resolve. Release tooling
    only.
  • The post-publish verification is now testable end to end (QCLI-304). It
    moved out of main() into verifyPublishedRelease, with every read
    injectable except the wrapper's anonymous consumer read. A test now makes the
    0.7.1 failure happen through that real read: the wrapper's write succeeded
    but the public packument does not list the version yet. It shows that no
    success line prints until a plain read lists the version. The runbook
    publish section now says what "verified" means. Release tooling only.
  • A version bump now fails fast if bun.lock still pins the old platform
    versions
    (QCLI-292). CI's bun install --frozen-lockfile does not notice
    at bump time, because the new version isn't on the registry yet. It failed
    only after publish, on an unrelated pull request (the 0.6.2 breakage). The
    new lockfile_pins source gate (bun run check:lockfile) compares the six
    pins to package.json and names bun install as the fix. Release tooling
    only.