feat(hooks): add task references to hooks and watch_files#8400
Conversation
Allow hooks and watch_files to reference mise tasks instead of inline
scripts using `{ task = "name" }` syntax. Tasks are executed as
subprocesses via `mise --cd <root> run <task>`, which naturally respects
MISE_NO_HOOKS and reuses the full task system (deps, env, etc.).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a great new feature allowing hooks and watch_files to reference mise tasks directly. The implementation is solid, with good test coverage for the new functionality. I've made two suggestions for improvement: one to enhance the JSON schema for watch_files to be more strict, and another to ensure consistency in environment variable handling between hooks and watch_files.
| env.insert( | ||
| "MISE_PROJECT_ROOT".to_string(), | ||
| root.to_string_lossy().to_string(), | ||
| ); |
There was a problem hiding this comment.
For consistency with how hooks are handled, consider setting the MISE_CONFIG_ROOT environment variable here as well. In hooks.rs, both MISE_PROJECT_ROOT and MISE_CONFIG_ROOT are set to the root path. This would also address the TODO in the execute function in this file.
| env.insert( | |
| "MISE_PROJECT_ROOT".to_string(), | |
| root.to_string_lossy().to_string(), | |
| ); | |
| env.insert( | |
| "MISE_PROJECT_ROOT".to_string(), | |
| root.to_string_lossy().to_string(), | |
| ); | |
| env.insert( | |
| "MISE_CONFIG_ROOT".to_string(), | |
| root.to_string_lossy().to_string(), | |
| ); |
Greptile SummaryThis PR adds task reference support to hooks and watch_files, allowing configuration like Key Changes:
Areas for Improvement:
Confidence Score: 4/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant User
participant mise
participant Hook System
participant Task Executor
participant Task
User->>mise: trigger hook (e.g., enter directory)
mise->>Hook System: run_one_hook_with_context()
alt Hook has task reference
Hook System->>Hook System: Check h.task_name.is_some()
Hook System->>Task Executor: execute_task()
Note over Task Executor: Set MISE_NO_HOOKS=1<br/>to prevent recursion
Task Executor->>Task Executor: cmd("mise", ["--cd", root, "run", task_name])
Task Executor->>Task: Execute task as subprocess
Task-->>Task Executor: Task output
Task Executor-->>Hook System: Result
else Hook has script
Hook System->>Hook System: execute()
Note over Hook System: Render template<br/>and run script
Hook System-->>mise: Result
end
Hook System-->>mise: Hook completed
mise-->>User: Continue
Last reviewed commit: 7df3342 |
| let result = if let Some(task_name) = &wf.task { | ||
| execute_task(config, ts, &root, task_name, files).await | ||
| } else if let Some(run) = &wf.run { | ||
| execute(config, ts, &root, run, files).await | ||
| } else { | ||
| warn!("watch_file hook has neither run nor task set, skipping"); | ||
| continue; |
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add warning in watch_files when both run and task are set - Remove unreachable task+shell guard in hooks (serde untagged makes it impossible) - Fix schema oneOf overlap for hooks by removing redundant string array variant - Add oneOf constraint to watch_files schema enforcing exactly one of run/task Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
bugbot run |
|
Shouldn't this also be extended to (custom) |
|
not sure about that yet, I think in general prepare steps should not be using tasks since they shouldn't be that complicated |
Hyperfine Performance
|
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.2.24 x -- echo |
28.9 ± 0.7 | 27.7 | 31.6 | 1.18 ± 0.04 |
mise x -- echo |
24.5 ± 0.6 | 23.2 | 26.3 | 1.00 |
✅ Performance improvement for x -- echo is 18% |
mise env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.2.24 env |
29.0 ± 0.9 | 27.3 | 36.1 | 1.23 ± 0.05 |
mise env |
23.5 ± 0.5 | 22.6 | 25.4 | 1.00 |
✅ Performance improvement for env is 23% |
mise hook-env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.2.24 hook-env |
29.8 ± 0.8 | 28.2 | 34.0 | 1.22 ± 0.04 |
mise hook-env |
24.4 ± 0.5 | 23.4 | 27.0 | 1.00 |
✅ Performance improvement for hook-env is 22% |
mise ls
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.2.24 ls |
23.9 ± 0.6 | 22.4 | 27.8 | 1.07 ± 0.04 |
mise ls |
22.3 ± 0.7 | 21.2 | 27.3 | 1.00 |
xtasks/test/perf
| Command | mise-2026.2.24 | mise | Variance |
|---|---|---|---|
| install (cached) | 166ms | 153ms | +8% |
| ls (cached) | 91ms | 83ms | +9% |
| bin-paths (cached) | 99ms | ✅ 87ms | +13% |
| task-ls (cached) | 845ms | 829ms | +1% |
✅ Performance improvement: bin-paths cached is 13%
### 🚀 Features - **(hooks)** add task references to hooks and watch_files by @jdx in [#8400](#8400) - **(prepare)** add git-submodule built-in provider by @jdx in [#8407](#8407) - **(prepare)** add human-readable stale reasons to prepare output by @jdx in [#8408](#8408) - **(prepare)** add dependency ordering to prepare steps by @jdx in [#8401](#8401) - **(prepare)** add --explain flag for provider diagnostics by @jdx in [#8409](#8409) - **(prepare)** add per-provider timeout support by @jdx in [#8405](#8405) - **(prepare)** add blake3 content-hash freshness checking by @jdx in [#8404](#8404) - **(tasks)** monorepo vars and per-task vars by @halms in [#8248](#8248) ### 🐛 Bug Fixes - **(aqua)** restore bin_paths disk cache with fresh_file invalidation by @jdx in [#8398](#8398) - **(idiomatic)** use generic parser for idiomatic files by @risu729 in [#8171](#8171) - **(install)** apply precompiled options to all platforms in lockfile by @jdx in [#8396](#8396) - **(install)** normalize "v" prefix when matching lockfile versions by @jdx in [#8413](#8413) - **(prepare)** improve git submodule parser and fix check_staleness error handling by @jdx in [#8412](#8412) - **(python)** respect precompiled settings in lock file generation by @jdx in [#8399](#8399) - **(python)** clarify uv_venv_auto docs + prevent uv shim recursion in venv creation by @halms in [#8402](#8402) - **(task)** remove deprecated `# mise` task header syntax by @jdx in [#8403](#8403) - **(vfox)** avoid eager metadata loading during config file detection by @jdx in [#8397](#8397) - clarify GitHub attestations to be artifact ones by @scop in [#8394](#8394) - ignore comments in idiomatic version files by @iloveitaly in [#7682](#7682) ### 🚜 Refactor - unify archive detection by @risu729 in [#8137](#8137) ### 📚 Documentation - remove duplicated docs for npm.package_manager by @risu729 in [#8414](#8414)
|
❔ This enables us to reference tasks by name, but not pass parameters to it, correct? |
Summary
{ task = "name" }syntaxmise --cd <root> run <task>, which naturally respectsMISE_NO_HOOKS=1and reuses the full task system (deps, env, etc.)enter = ["echo hello", { task = "setup" }]Closes #8392 (partial)
TOML syntax
Test plan
HookDefdeserialization ofTaskRefvarianttest_hooks_task_ref— task runs on enter/leave/preinstall hooks, mixed script+task arraystest_hooks,test_hooks_error_handling,test_hooks_global)🤖 Generated with Claude Code
Note
Medium Risk
Adds a new execution path that shells out to
mise runduring hook/watch execution, which can affect environment propagation and experimental feature gating. Risk is moderated by keeping existing script-based behavior intact and adding coverage plus schema validation.Overview
Enables task-backed hooks by allowing
[hooks]entries to reference a mise task via{ task = "name" }, including mixed arrays of scripts and task refs; hook execution now dispatches either to existing inline script handling or to a new subprocess call tomise run(withMISE_NO_HOOKS=1and the usual hook env vars).Extends
[[watch_files]]to supporttask = "..."as an alternative torun, validates this in the JSON schema (exactly one ofrun/task), and updates parsing to template-rendertasknames. Adds docs and an e2e test covering task refs forenter/leave/preinstalland mixed script+task arrays.Written by Cursor Bugbot for commit 18468a9. This will update automatically on new commits. Configure here.