Repository navigation
feat(eval): add --format=json for structured template output - #3106
Merged
Merged
Conversation
`wt step eval` printed only the bare rendered result to stdout, with the
template name / source / result triple reachable solely from the `-v` human
lane on stderr. There was no machine-readable representation of an expansion.
Add `--format=json`, emitting `{name, template, result}` to stdout — the
structured analog of the `-v` view and a match for `hook show --format=json`.
The lanes compose: `--format=json -v` keeps JSON on stdout and the human
expansion view on stderr.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Resolved src/commands/eval.rs: combined #3099's labeled source/result verbose view (and its trailing-blank separator) with this branch's new --format=json output. Regenerated eval_format_json_verbose snapshot for the relabeled -v view. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The dedicated `## JSON output` section restated the trivial 3-key shape
already named in the `--format` flag doc, and no sibling `wt step` command
carries such a section. Remove it; the flag description `JSON prints
{name, template, result} to stdout` carries the shape.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
worktrunk-bot
approved these changes
Jun 17, 2026
max-sixty
added a commit
that referenced
this pull request
Jun 18, 2026
…ts them (#3112) Follow-up to #3108. That PR made clap render `--format`'s values inline as `[possible values: …]`, but five flags still carried a hand-written value parenthetical in their doc comment, so the list rendered twice — three times in `wt list statusline -h`: ``` --format <FORMAT> Output format (table, json, claude-code) [default: table] [possible values: table, json, claude-code] ``` This drops the parenthetical (→ bare `/// Output format`) from every `--format` flag that does **not** hide possible-values, leaving clap's inline list as the single source: `wt list statusline`, `wt step for-each`, `wt step prune`, `wt config show`, `wt config state vars list`. The deliberate hiders are left untouched — they set `hide_possible_values = true`, so their parenthetical is the *only* value list: `wt list`, `wt config state get` (both suppress the `claude-code` value, which is meaningless for them), and the shared `GlobalFormatFlag` for `config state cache`/`logs`/`hints`/`ci-status`/`marker`. The rule: if clap prints the list, drop the hand-written one; if clap's list is suppressed, keep it. For `wt list statusline`, `claude-code`'s non-obvious behavior stays visible in the long-help possible-values block (`- claude-code: Claude Code statusline mode (reads context from stdin)`) and the dedicated "Claude Code mode" section. This also regenerates a stale mirror: `wt step eval --format`'s `step.md` section was out of sync with the binary (expanded block vs. terse) because #3106 added that flag with the old `SwitchFormat` while #3108 trimmed it — their merge order left `test_docs_are_in_sync` failing on `main`. This PR fixes that. > _This was written by Claude Code on behalf of max_ Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Merged
max-sixty
added a commit
that referenced
this pull request
Jun 18, 2026
Release v0.60.0 (minor bump from 0.59.0). Minor because semver-checks flagged a breaking library-API change and five new features landed since v0.59.0. The data-loss surface review (4 independent finders) cleared the one change that touches it (relocating dirty linked worktrees, #3104). ### Improved - Package installs now complete branch/worktree names via dynamic registration (#3105, thanks @bendrucker) - `wt step relocate` moves dirty linked worktrees (#3104, thanks @lunaynx for reporting) - `--dry-run` previews print to stdout (#3085) - Picker gutter distinguishes local (`/`) and remote (`|`) branches (#3115) - `wt list --format=json` gains structured `repo`/`ci.repo` metadata (#3021, thanks @jeremy0dell) - `wt step eval --format=json` (#3106) - `--format=claude-code` rejected on `wt list` / `wt config state get` (#3116) ### Fixed - `cargo install worktrunk` builds from crates.io again (#3124, fixes #3123, thanks @kerrickstaley for reporting) - Tab-completion works in repos with no commits (#3097, closes #3094) - `wt config state get ci-status --format=json` honors `[forge].platform` (#3120) ### Documentation - `wt list --help` example tables fit the terminal (#3125) - `/wt-switch-create` cross-repo handling reworked (#3118) - Help-text and web-doc refinements (#3096, #3108, #3110, #3112, #3126) Full notes in `CHANGELOG.md`. > _This was written by Claude Code on behalf of max_
social4hyq
pushed a commit
to social4hyq/homebrew-core
that referenced
this pull request
Sep 20, 2026
worktrunk 0.60.0 Created-by: HarmonybrewBot Commit-by: HarmonybrewBot Merged-by: HarmonybrewBot Description: Created by `brew bump` --- Created with `brew bump-formula-pr`.<details> <summary>release notes</summary> <pre>## Release Notes ### Improved - **Package installs complete branch and worktree names**: A plain `brew install worktrunk` (or other package install) now tab-completes branch and worktree names, not just subcommands and flags. `wt config shell completions <shell>` emits a dynamic registration that calls the binary at completion time (the maintained `clap_complete::env` path), matching what `gh`, `rustup`, and `kubectl` ship. ([#3105](max-sixty/worktrunk#3105), thanks @bendrucker) - **`wt step relocate` moves dirty linked worktrees**: Relocating a linked worktree with uncommitted or untracked changes no longer skips it. `git worktree move` carries those files along, so the dirty-skip was a worktrunk policy rather than a git limitation. The main worktree still skips when dirty (without `--commit`), since its relocation falls back to `git checkout`, which refuses to switch over a dirty tree. ([#3104](max-sixty/worktrunk#3104), thanks @lunaynx for reporting) - **`--dry-run` previews print to stdout**: `wt hook <type>`, `wt step relocate`, `wt step prune`, `wt step copy-ignored`, and `wt config shell install`/`uninstall` now send their `--dry-run` preview to stdout (the command's answer) while narration stays on stderr. This matches `wt list`, `git clean -n`, and `terraform plan`, and keeps previews pageable and pipeable. (Breaking: scripts reading these previews from stderr should now read stdout) ([#3085](max-sixty/worktrunk#3085)) - **Picker gutter distinguishes local and remote branches**: With `--branches` and `--remotes`, the `wt switch` picker marks each row's kind in the gutter: `/` for a local branch without a worktree and `|` for a remote branch, alongside the existing `@`/`^`/`+` worktree glyphs. ([#3115](max-sixty/worktrunk#3115)) - **`wt list --format=json` gains structured `repo` metadata**: JSON output adds `repo` (the local checkout's primary remote) and `ci.repo` (the repository `ci.url` targets, which differs for fork PRs) objects carrying `host`/`owner`/`name`/`provider`; the existing `repo_url` and `ci.repo_url` strings remain. The provider honors the configured `[forge].platform` on hosts that can't be auto-detected. ([#3021](max-sixty/worktrunk#3021), thanks @jeremy0dell) - **`wt step eval --format=json`**: `wt step eval` gains a structured `{name, template, result}` JSON lane on stdout, the machine-readable analog of its `-v` view. Text mode is unchanged. ([#3106](max-sixty/worktrunk#3106)) - **`--format=claude-code` rejected where it never applied**: `wt list` and `wt config state get` accepted `--format=claude-code` silently and treated it as `table`; the value only ever meant anything on `wt list statusline`. Both now fail fast with `invalid value 'claude-code'`. (Breaking: `wt list --format=claude-code` and `wt config state get --format=claude-code` now error) ([#3116](max-sixty/worktrunk#3116)) ### Fixed - **`cargo install worktrunk` builds from crates.io**: Installing from crates.io failed to compile with `environment variable VERGEN_GIT_DESCRIBE not defined at compile time`, because the package archive has no `.git` for the build script to read. The version lookup now falls back to the cargo package version when git-describe is unavailable. ([#3124](max-sixty/worktrunk#3124), fixes [#3123](max-sixty/worktrunk#3123), thanks @kerrickstaley for reporting) - **Tab-completion works in repos with no commits**: `wt switch <TAB>` and `wt remove <TAB>` returned nothing on a fresh `git init` repo, because the unborn default branch has no entry under `refs/heads/`. Completion now also draws on worktree branches, so the unborn `main` (and any `wt switch --create` branch on an empty repo) completes. ([#3097](max-sixty/worktrunk#3097), closes [#3094](max-sixty/worktrunk#3094)) - **`wt config state get ci-status --format=json` honors `[forge].platform`**: On a self-hosted host the parser can't recognize (Gitea, Azure DevOps, GitHub Enterprise on a generic domain), this path reported `provider: "unknown"` while `wt list --format=json` reported the configured provider. All structured-output paths now route the `[forge].platform` override through one accessor, so they stay consistent. ([#3120](max-sixty/worktrunk#3120)) ### Documentation - **`wt list --help` example tables fit the terminal**: The captured `wt list` example tables in `--help` chop to terminal width with a dimmed ellipsis (matching real `wt list`) instead of word-wrapping and shearing their columns; hand-authored command examples still wrap. ([#3125](max-sixty/worktrunk#3125)) - **`/wt-switch-create` cross-repo handling reworked**: The Claude Code plugin command's skill reworks how it creates and enters a worktree in another repo, built around what the harness actually does (`EnterWorktree` re-roots within the current repo; a `cd` reaches another repo when it's in `additionalDirectories`). The procedure dropped from five steps to three. ([#3118](max-sixty/worktrunk#3118)) - **Help-text and docs refinements**: `--format` help renders its values inline (`[possible values: table, json]`) instead of an expanded block; `wt switch` and `wt step push` help got smaller clarifications; and web-doc terminal blocks no longer wrap command-only lines. ([#3096](max-sixty/worktrunk#3096), [#3108](max-sixty/worktrunk#3108), [#3110](max-sixty/worktrunk#3110), [#3112](max-sixty/worktrunk#3112), [#3126](max-sixty/worktrunk#3126)) ## Install worktrunk 0.60.0 ### Install prebuilt binaries via shell script ```sh curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.60.0/worktrunk-installer.sh | sh && wt config shell install ``` ### Install prebuilt binaries via powershell script ```sh powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.60.0/worktrunk-installer.ps1 | iex"; git-wt config shell install ``` ### Install prebuilt binaries via Homebrew ```sh brew install worktrunk && wt config shell install ``` ## Download worktrunk 0.60.0 | File | Platform | Checksum | |--------|----------|----------| | [worktrunk-aarch64-apple-darwin.tar.xz](https://github.com/max-sixty/worktrunk/releases/download/v0.60.0/worktrunk-aarch64-apple-darwin.tar.xz) | Apple Silicon macOS | [checksum](https://github.com/max-sixty/worktrunk/releases/download/v0.60.0/worktrunk-aarch64-apple-darwin.tar.xz.sha256) | | [worktrunk-x86_64-apple-darwin.tar.xz](https://github.com/max-sixty/worktrunk/releases/download/v0.60.0/worktrunk-x86_64-apple-darwin.tar.xz) | Intel macOS | [checksum](https://github.com/max-sixty/worktrunk/releases/download/v0.60.0/worktrunk-x86_64-apple-darwin.tar.xz.sha256) | | [worktrunk-x86_64-pc-windows-msvc.zip](https://github.com/max-sixty/worktrunk/releases/download/v0.60.0/worktrunk-x86_64-pc-windows-msvc.zip) | x64 Windows | [checksum](https://github.com/max-sixty/worktrunk/releases/download/v0.60.0/worktrunk-x86_64-pc-windows-msvc.zip.sha256) | | [worktrunk-aarch64-unknown-linux-musl.tar.xz](https://github.com/max-sixty/worktrunk/releases/download/v0.60.0/worktrunk-aarch64-unknown-linux-musl.tar.xz) | ARM64 MUSL Linux | [checksum](https://github.com/max-sixty/worktrunk/releases/download/v0.60.0/worktrunk-aarch64-unknown-linux-musl.tar.xz.sha256) | | [worktrunk-x86_64-unknown-linux-musl.tar.xz](https://github.com/max-sixty/worktrunk/releases/download/v0.60.0/worktrunk-x86_64-unknown-linux-musl.tar.xz) | x64 MUSL Linux | [checksum](https://github.com/max-sixty/worktrunk/releases/download/v0.60.0/worktrunk-x86_64-unknown-linux-musl.tar.xz.sha256) | ### Install via Cargo ```sh cargo install worktrunk && wt config shell install ``` ### Install via Winget (Windows) ```sh winget install max-sixty.worktrunk && git-wt config shell install ``` ### Install via AUR (Arch Linux) ```sh paru worktrunk-bin && wt config shell install ``` </pre> <p>View the full release notes at <a href="https://github.com/max-sixty/worktrunk/releases/tag/v0.60.0">https://github.com/max-sixty/worktrunk/releases/tag/v0.60.0</a>.</p> </details> <hr> See merge request: Harmonybrew/homebrew-core!11933
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
--format=jsontowt step eval, the structured counterpart to its-vview.wt step evalprinted only the bare rendered result to stdout; the template's name, source, and rendered result were reachable solely from the-vhuman lane on stderr, with no machine-readable form.--format=jsonemits{name, template, result}to stdout — the structured analog of the-vexpansion view, and consistent withwt hook show --format=jsonand the otherwt stepJSON lanes.Text mode is unchanged (bare result to stdout). The two lanes compose:
--format=json -vkeeps JSON on stdout and the human expansion view on stderr, sowt step eval --format=json -v … 2>/dev/nullyields clean JSON.Implementation mirrors the sibling
wt stepcommands: aSwitchFormatflag under theAutomationheading, an inlineserde_json::json!payload, and snapshot tests covering the JSON lane and the JSON +-vcomposition.