Skip to content

chore: bump communique to 1.0.1#850

Merged
jdx merged 11 commits intomainfrom
bump-communique-1.0.1
Apr 20, 2026
Merged

chore: bump communique to 1.0.1#850
jdx merged 11 commits intomainfrom
bump-communique-1.0.1

Conversation

@jdx
Copy link
Copy Markdown
Owner

@jdx jdx commented Apr 20, 2026

Summary

  • Bump communique from 0.1.9 to 1.0.1

🤖 Generated with Claude Code


Note

Medium Risk
Adds new CLI flags and a new plan-generation path that changes how hooks can be invoked (--why implies planning and --json is validated), which could affect user workflows and output compatibility. Includes a tool version bump (communique) but primary risk is in new planning/condition-evaluation logic matching runtime behavior.

Overview
Adds richer hook planning introspection: hk <hook> --why[=<STEP>] now prints a plan with detailed inclusion/exclusion reasons (and can focus on a single step), and --json can emit the plan as structured JSON for --plan/--why.

Implements a new Plan model (src/plan.rs) and rewrites Hook::plan to analyze steps (filters, profiles, skip-step sources, dependencies, and condition/step_condition evaluation) while suppressing progress noise; --why <step> --json filters the JSON to the focused step and prunes parallel group references.

Updates CLI docs/usage metadata to document -J/--json and -W/--why, adds validation so --json errors unless paired with planning (except when used for global trace JSON), and bumps communique to 1.0.1 in mise.lock.

Reviewed by Cursor Bugbot for commit e25b701. Bugbot is set up for automated code reviews on this repo. Configure here.

jdx and others added 11 commits April 18, 2026 20:29
- `--plan` / `-P`: print a dry-run plan showing which steps would run,
  which would be skipped, and why — without executing any commands.
- `--why [STEP]` / `-W`: show all reasons per step. Pass a step name to
  focus on one; omit the value to show details for every step. Implies
  `--plan`.
- `--json` / `-J`: emit the plan as JSON (requires `--plan`) for tooling.

The plan is built via static analysis (reusing `build_step_jobs` and
`profile_skip_reason`) so it never executes step commands. It reports:
step status (included/skipped), parallel group membership, dependencies,
matched file count, and a structured list of reasons (filter match,
profile include/exclude, condition true/false, CLI/env/config skip,
missing required env, no command for run type).

Removes the previous `--plan` stub that panicked via `todo!()`.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Correctness fixes (reported by reviewers on #848):

- Mirror runtime profile-skip when `job_condition` is set.
  `build_step_jobs` defers profile checks to runtime when a condition is
  present (job_builder.rs:153) so the old plan reported such steps as
  Included. `analyze_step` now calls `profile_skip_reason` explicitly in
  that path.
- Match runtime truthiness for `condition`. The runtime only skips on a
  literal `Bool(false)` — non-boolean values (e.g. strings from `exec()`)
  are truthy. Plan used `as_bool().unwrap_or(false)` which treated them
  as falsy and reported Skipped incorrectly.
- Evaluate `step_condition` (was ignored). The runtime checks it in
  execution.rs before building jobs; the plan now mirrors that.

Flag fix:

- `--json` no longer requires `--plan` at the clap level, so
  `--why --json` works. Validated in code: errors with
  "--json requires --plan or --why" otherwise.

Refactors:

- Extract `build_skip_steps` and `build_expr_ctx` helpers used by
  `plan`, `stats`, and `run`.
- Add `RunType::as_str()` and `Display` so the "check"/"fix" match is no
  longer duplicated.

Adds five regression bats tests covering each correctness fix and the
`--why --json` / `--json` without `--plan` cases.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
build_step_jobs populates job.files before applying skip_reason (see
job_builder.rs lines 81-158), so profile-skipped steps still have a
meaningful matched file count. The plan was hardcoding zero.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Replace `Ok(val) if val == expr::Value::Bool(false)` with the direct
pattern `Ok(expr::Value::Bool(false))`. The guard-style match was the
newly-introduced CI failure on `mise run lint`.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
analyze_step pushed ConditionTrue first when a truthy condition passed,
so print_plan's headline (reasons.first()) contradicted the icon when
the step was later skipped for another reason (e.g. no files matched).
print_plan now picks the first skip-flavored reason as the headline when
status is Skipped; verbose --why still shows every reason.

Adds ReasonKind::is_skip to classify reason kinds.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
`print_plan` picks the headline reason by finding the first skip-flavored
entry, which may be at any index. The verbose detail loop used
`.skip(1)`, so when the headline came from index > 0 it silently dropped
the first reason and reprinted the headline. Track the headline's index
and `continue` past it instead.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
The top-level CLI has a global --json flag for trace/log output. My
prior validation (\"--json requires --plan or --why\") rejected
\`hk --trace --json check\` because clap populates both the global
\`args.json\` and the subcommand-level \`opts.json\` for the shared
flag name.

Remove the validation. --json alone continues to mean global JSON
output (unchanged), and is only interpreted as plan-JSON when --plan
or --why is also set (in which case plan() is entered).

Drops the now-invalid regression test.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
…m variant

- JSON output of \`--why <step> --json\` was ignoring the step focus and
  emitting every step. It now retains only the focused step (and its
  parallel group entry), matching the text renderer.
- Remove unused \`ReasonKind::Always\` — never constructed.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
…e --json

The previous commit dropped the validation to unbreak `hk --trace --json check`,
but that made `hk check --json` silently run the hook with no JSON output.

Reinstate the guard, gated on whether the user actually asked for
tracing: if `--trace`, `HK_TRACE=json`, or `HK_JSON=1` is set, the global
--json is legitimately active and we skip the error. Otherwise a bare
`--json` without --plan/--why errors with
"--json requires --plan or --why".

Adds `CliSnapshot.trace` and `Settings::cli_trace()` to plumb the
top-level --trace flag into HookOptions.

Regression tests: both the error case and the `hk --trace --json` happy
path are covered.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
`--why <step> --json` filtered `plan.steps` but left the retained
group's `step_ids` pointing at siblings that were filtered out,
producing dangling references for tooling that follows stepIds. Now
also retain only the kept step names in each group and drop groups
that become empty.

Extends the regression test with a 3-step config so the group check
actually has something to prune.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 20, 2026

Greptile Summary

This PR bumps the communique mise tool from 0.1.9 to 1.0.1 and simultaneously renames the Rust crate from communique to clx (version 2.0). All source files that previously imported communique::progress::* now import clx::progress::*, and the updated mise.lock pins new checksums for all platforms. Generated CLI documentation and the hk.usage.kdl file are regenerated to reflect the update.

Confidence Score: 5/5

This PR is safe to merge — it is a straightforward dependency rename with no logic changes.

All changes are mechanical renaming of communiqueclx across source files and a lockfile bump with verified checksums. No logic, algorithm, or interface changes are present.

No files require special attention.

Important Files Changed

Filename Overview
Cargo.toml Dependency renamed from communique to clx = "2.0" — no other changes.
mise.lock Bumps communique tool entry from 0.1.9 to 1.0.1 with new platform checksums; all other tool versions unchanged.
src/main.rs Updated communique:: references to clx:: (progress flush/interval calls); no logic changes.
src/cli/mod.rs Import updated from communique::progress::ProgressOutput to clx::progress::ProgressOutput; adds clx::osc::configure call for terminal progress; no logic change.
src/hook.rs All communique::progress imports replaced with clx::progress; no functional changes.
src/step_group.rs Import updated to clx::progress; no logic change.
hk.usage.kdl Regenerated CLI usage documentation; no manual changes needed.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Cargo.toml] -->|was: communique| B[communique crate v0.x]
    A -->|now: clx = 2.0| C[clx crate v2.0]
    C --> D[clx::progress - ProgressJob, ProgressOutput, etc.]
    C --> E[clx::osc - terminal OSC configure]
    D --> F[src/main.rs]
    D --> G[src/cli/mod.rs]
    D --> H[src/hook.rs]
    D --> I[src/step_group.rs]
    E --> G
    J[mise.lock] -->|tool: communique 0.1.9 → 1.0.1| K[communique CLI tool]
    K -->|generates| L[docs/cli/*.md]
    K -->|generates| M[hk.usage.kdl]
Loading

Reviews (1): Last reviewed commit: "chore: bump communique to 1.0.1" | Re-trigger Greptile

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a robust planning and introspection feature for hooks, adding the --plan, --why, and --json CLI flags. These allow users to preview execution steps and understand the inclusion or exclusion logic for each step. The changes include a new plan module for serialization, a detailed analysis engine in hook.rs, and a suite of integration tests. The review feedback identifies a logic bug regarding empty job sets, the use of unstable Rust let-chains that would break stable builds, and opportunities to simplify code using newly implemented trait extensions.

Comment thread src/hook.rs
}
};

let all_skipped = !jobs.is_empty() && jobs.iter().all(|j| j.skip_reason.is_some());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The logic for all_skipped incorrectly assumes that an empty jobs vector means the step is included. If build_step_jobs returns an empty vector (e.g., when no files match and no specific skip reason is generated), the step should be considered skipped, not included. This results in steps with 0 matching files being marked with a success checkmark in the plan output.

Suggested change
let all_skipped = !jobs.is_empty() && jobs.iter().all(|j| j.skip_reason.is_some());
let all_skipped = jobs.is_empty() || jobs.iter().all(|j| j.skip_reason.is_some());

Comment thread src/hook.rs
// in runner.rs. Mirror that here so a profile-skipped step isn't
// reported as Included.
if step.job_condition.is_some()
&& let Some(reason) = step.profile_skip_reason()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This line uses the unstable let-chains feature (&& let Some(...)). Unless this project is strictly targeting nightly Rust, this will cause a compilation error on stable toolchains. Consider using a nested if let or matches! instead.

Suggested change
&& let Some(reason) = step.profile_skip_reason()
if step.job_condition.is_some() {
if let Some(reason) = step.profile_skip_reason() {
reasons.push(skip_reason_to_reason(&reason));
return (StepStatus::Skipped, reasons, Some(file_count));
}
}

Comment thread src/hook.rs
let mut last_group: Option<String> = None;
for step in &plan.steps {
if let Some(focus) = &focus_step
&& focus != &step.name
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This line uses an unstable let-chain which will fail to compile on stable Rust. It is recommended to use a standard if let pattern for compatibility.

Suggested change
&& focus != &step.name
if let Some(focus) = &focus_step {
if focus != &step.name {
continue;
}
}

Comment thread src/hook.rs
continue;
}
if step.parallel_group_id != last_group
&& let Some(gid) = &step.parallel_group_id
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Another instance of an unstable let-chain. This should be refactored to support stable Rust toolchains.

Suggested change
&& let Some(gid) = &step.parallel_group_id
if step.parallel_group_id != last_group {
if let Some(gid) = &step.parallel_group_id {
println!(" {} {}", style::ndim("[parallel group]"), style::ndim(gid));
}
}

Comment thread src/hook.rs
Comment on lines +1448 to +1452
let rt_str = match rt {
RunType::Check => "check",
RunType::Fix => "fix",
};
(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This match block is redundant now that RunType implements Display and provides an as_str() method. You can simplify the formatting logic.

Suggested change
let rt_str = match rt {
RunType::Check => "check",
RunType::Fix => "fix",
};
(
SkipReason::NoCommandForRunType(rt) => (
ReasonKind::NoCommand,
Some(format!("no command defined for run type: {rt}")),
),

@jdx jdx merged commit 660eae7 into main Apr 20, 2026
28 of 29 checks passed
@jdx jdx deleted the bump-communique-1.0.1 branch April 20, 2026 03:00
@jdx jdx mentioned this pull request Apr 20, 2026
jdx added a commit that referenced this pull request Apr 23, 2026
### 🚀 Features

- **(check)** implement --plan, --why, and --json by
[@jdx](https://github.com/jdx) in
[#848](#848)
- **(cocogitto)** add cocogitto conventional commits config to hk
builtin config by [@hituzi-no-sippo](https://github.com/hituzi-no-sippo)
in [#838](#838)
- **(git)** support GIT_DIR/GIT_WORK_TREE for bare-repo dotfile managers
by [@jdx](https://github.com/jdx) in
[#847](#847)
- **(install)** use Git 2.54 config-based hooks with --global support by
[@jdx](https://github.com/jdx) in
[#853](#853)

### 🐛 Bug Fixes

- use text progress in CI by [@jdx](https://github.com/jdx) in
[#845](#845)

### 📚 Documentation

- generalize agent guidelines by [@jdx](https://github.com/jdx) in
[#846](#846)
- add releases nav and aube lock by [@jdx](https://github.com/jdx) in
[#849](#849)

### 🔍 Other Changes

- bump communique to 1.0.1 by [@jdx](https://github.com/jdx) in
[#850](#850)

### 📦️ Dependency Updates

- update actions-rust-lang/setup-rust-toolchain digest to 2b1f5e9 by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#832](#832)
- update anthropics/claude-code-action digest to c3d45e8 by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#833](#833)
- update rust crate tokio to v1.52.1 by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#834](#834)
- update actions/upload-pages-artifact action to v5 by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#835](#835)
- update taiki-e/upload-rust-binary-action digest to f0d45ae by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#839](#839)
- update rust crate clx to v2 by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#836](#836)
- update anthropics/claude-code-action digest to 0d2971c by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#841](#841)
- update anthropics/claude-code-action digest to 38ec876 by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#842](#842)
- lock file maintenance by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#851](#851)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk release bookkeeping: version bumps and doc/CLI artifact
updates, plus minor dependency patch updates in `Cargo.lock`. No
functional Rust source changes are included in this diff.
> 
> **Overview**
> Bumps `hk` to **v1.44.0** and publishes the corresponding release
notes in `CHANGELOG.md`.
> 
> Updates generated/packaged artifacts to match the new version (CLI
docs/specs and Pkl package URLs in docs/examples), and refreshes
`Cargo.lock` for the release (including patch-level updates like
`rustls` and `winnow`).
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
a36c7a6. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: mise-en-dev <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant