fix(ui): prevent OSC 9;4 progress sequences from being written to non-terminals#6615
fix(ui): prevent OSC 9;4 progress sequences from being written to non-terminals#6615
Conversation
When a task's run block referenced project tasks (e.g., `{ task = "//projects/backend:hello" }`),
those tasks were not being loaded properly, causing "task not found" errors.
The root cause was that `inject_and_wait` was calling `config.tasks_with_aliases()`, which uses
a default `TaskLoadContext` with `load_all: false` and empty `path_hints`. This context won't
load tasks from project subdirectories in monorepo mode.
The fix creates a proper `TaskLoadContext` from the task specs being injected, ensuring that
all necessary project tasks are loaded before attempting to resolve and execute them.
Fixes: #6615
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
…-terminals OSC 9;4 escape sequences were being written to stderr even when it wasn't a terminal, causing visible escape codes in piped/captured output (e.g., in e2e tests). Added a check to only write OSC sequences when stderr is user-attended (i.e., an actual terminal). This prevents escape codes from appearing in logs, piped output, or CI environments. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Pull Request Overview
Fixes OSC 9;4 escape sequences appearing in non-terminal output by adding a terminal check before writing progress indicators.
- Added terminal detection to prevent escape codes in redirected output and CI environments
- Fixed task loading context to properly handle project tasks in monorepo environments
- Added comprehensive test coverage for monorepo task execution scenarios
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/ui/osc.rs | Added terminal check to prevent OSC sequences in non-terminal stderr |
| src/cli/run.rs | Enhanced task loading with proper context for project task resolution |
| e2e/tasks/test_task_monorepo_run_project_tasks | Added comprehensive test for monorepo project task execution |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| use crate::file::display_path; | ||
| use crate::task::task_file_providers::TaskFileProvidersBuilder; | ||
| use crate::task::{Deps, GetMatchingExt, Task}; | ||
| use crate::task::{Deps, GetMatchingExt, Task, TaskLoadContext}; |
There was a problem hiding this comment.
The import of TaskLoadContext appears to be added but the original import line was not properly removed, creating a potential duplicate import issue.
| let ctx = TaskLoadContext::from_patterns(specs.iter().map(|s| { | ||
| let (name, _) = split_task_spec(s); | ||
| name | ||
| })); |
There was a problem hiding this comment.
[nitpick] The closure can be simplified by using a more direct mapping approach without the intermediate destructuring.
| let ctx = TaskLoadContext::from_patterns(specs.iter().map(|s| { | |
| let (name, _) = split_task_spec(s); | |
| name | |
| })); | |
| let ctx = TaskLoadContext::from_patterns(specs.iter().map(|s| split_task_spec(s).0)); |
…6614) ## Summary - Fixes project tasks not being resolved when called from root task run blocks - Creates proper TaskLoadContext from task specs to ensure all necessary project tasks are loaded - Adds comprehensive e2e test to prevent regression ## Problem When a task's run block referenced project tasks (e.g., `{ task = "//projects/backend:hello" }`), those tasks were not being loaded properly, causing "task not found" errors. This occurred even though the same tasks worked correctly when referenced via `depends`. ## Root Cause The `inject_and_wait` function was calling `config.tasks_with_aliases()`, which uses a default `TaskLoadContext` with `load_all: false` and empty `path_hints`. This context won't load tasks from project subdirectories in monorepo mode. ## Solution Modified `inject_and_wait` to: 1. Create a `TaskLoadContext` from the task specs being injected 2. Use `config.tasks_with_context(Some(&ctx))` instead of `config.tasks_with_aliases()` 3. Manually build the tasks_map with aliases (duplicating the logic from `tasks_with_aliases()`) This ensures that when a task references project tasks in its run block, those project directories are included in the TaskLoadContext path hints, causing their tasks to be loaded. ## Test plan - [x] New e2e test `test_task_monorepo_run_project_tasks` passes - [x] Tests 3 scenarios: - Calling single project task from root task run block - Calling project task via depends (existing functionality) - Calling multiple project tasks from root task run block - [x] Existing monorepo tests pass (`test_task_monorepo_dependencies`, `test_task_run_depends`) - [x] Lint checks pass Fixes: #6615 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Ensure project tasks referenced in run blocks are resolved using TaskLoadContext; add e2e coverage for monorepo task invocation. > > - **CLI/Tasks**: > - Update `inject_and_wait` in `src/cli/run.rs` to construct a `TaskLoadContext` from run-block specs and use `config.tasks_with_context(...)`, then rebuild alias map to resolve tasks (including monorepo project tasks). > - Import `TaskLoadContext` to support context-aware task loading. > - **E2E Tests**: > - Add `e2e/tasks/test_task_monorepo_run_project_tasks` validating: > - Root run-block invoking `//projects/backend:hello`. > - Dependency-based invocation from root. > - Multiple project tasks in a run block (backend and frontend). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 4f8ad02. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: Claude <noreply@anthropic.com>
Hyperfine Performance
|
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2025.10.6 x -- echo |
19.7 ± 1.0 | 18.7 | 25.7 | 1.00 |
mise x -- echo |
20.8 ± 1.1 | 18.7 | 27.1 | 1.05 ± 0.07 |
mise env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2025.10.6 env |
19.3 ± 1.0 | 18.1 | 26.6 | 1.00 |
mise env |
19.8 ± 0.9 | 18.0 | 25.5 | 1.03 ± 0.07 |
mise hook-env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2025.10.6 hook-env |
18.8 ± 0.8 | 17.3 | 25.8 | 1.00 |
mise hook-env |
19.7 ± 0.9 | 17.8 | 26.7 | 1.05 ± 0.07 |
mise ls
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2025.10.6 ls |
16.5 ± 0.6 | 15.2 | 21.5 | 1.00 |
mise ls |
16.8 ± 1.0 | 15.4 | 23.2 | 1.02 ± 0.07 |
xtasks/test/perf
| Command | mise-2025.10.6 | mise | Variance |
|---|---|---|---|
| install (cached) | 209ms | ✅ 111ms | +88% |
| ls (cached) | 67ms | 67ms | +0% |
| bin-paths (cached) | 71ms | 73ms | -2% |
| task-ls (cached) | 491ms | 489ms | +0% |
✅ Performance improvement: install cached is 88%
### 📦 Registry - add lazyssh by @TyceHerrman in [#6610](#6610) ### 🚀 Features - **(config)** Add a ceiling to how mise searchs for config & tasks by @richardthe3rd in [#6041](#6041) ### 🐛 Bug Fixes - **(task)** use config_root instead of project_root for task base path by @risu729 in [#6609](#6609) - **(task)** resolve project tasks in run blocks using TaskLoadContext by @jdx in [#6614](#6614) - **(task)** dont truncate task message when CI is set by @roele in [#6620](#6620) - **(ui)** prevent OSC 9;4 progress sequences from being written to non-terminals by @jdx in [#6615](#6615) ### Chore - remove cosign/slsa-verifier from mise.toml by @jdx in [#6616](#6616) ### New Contributors - @richardthe3rd made their first contribution in [#6041](#6041)
## Summary
Fixes issue where tasks using `run = { task = ":hello" }` syntax would
fail to resolve local task references in monorepo projects.
**Problem:**
When a monorepo project task used `:task` syntax in a `run` block to
reference another local task, the pattern wasn't being resolved before
execution, causing the error:
```
':task' pattern should be expanded before matching
```
For example:
```toml
[tasks.runs-hello]
run = { task = ":hello" } # This would fail
```
**Root Cause:**
The `exec_task_run_entries` function in `run.rs` was not resolving
`:task` patterns before calling `inject_and_wait`. While the
`resolve_task_pattern` function existed and was used for `depends`
blocks, it wasn't being applied to `run` blocks.
**Solution:**
Apply `resolve_task_pattern()` to task references in both
`RunEntry::SingleTask` and `RunEntry::TaskGroup` variants before
injecting them into the task scheduler. This resolves `:task` patterns
relative to the parent task's monorepo path.
**Changes:**
- `src/cli/run.rs`: Updated `exec_task_run_entries()` to resolve
patterns in both single task and task group run entries
- `e2e/tasks/test_task_monorepo_run_project_local_tasks`: New test
validating :task resolution in run blocks
## Test plan
- [x] New e2e test `test_task_monorepo_run_project_local_tasks` validates
the fix
- [x] All existing task dependency tests pass
- [x] All existing monorepo task tests pass
Fixes: jdx#6615
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
## Summary
Fixes issue where tasks using `run = { task = ":hello" }` syntax would
fail to resolve local task references in monorepo projects.
**Problem:**
When a monorepo project task used `:task` syntax in a `run` block to
reference another local task, the pattern wasn't being resolved before
execution, causing the error:
```
':task' pattern should be expanded before matching
```
For example:
```toml
[tasks.runs-hello]
run = { task = ":hello" } # This would fail
```
**Root Cause:**
The `exec_task_run_entries` function in `run.rs` was not resolving
`:task` patterns before calling `inject_and_wait`. While the
`resolve_task_pattern` function existed and was used for `depends`
blocks, it wasn't being applied to `run` blocks.
**Solution:**
Apply `resolve_task_pattern()` to task references in both
`RunEntry::SingleTask` and `RunEntry::TaskGroup` variants before
injecting them into the task scheduler. This resolves `:task` patterns
relative to the parent task's monorepo path.
**Changes:**
- `src/cli/run.rs`: Updated `exec_task_run_entries()` to resolve
patterns in both single task and task group run entries
- `e2e/tasks/test_task_monorepo_run_project_local_tasks`: New test
validating :task resolution in run blocks
## Test plan
- [x] New e2e test `test_task_monorepo_run_project_local_tasks` validates
the fix
- [x] All existing task dependency tests pass
- [x] All existing monorepo task tests pass
Fixes: jdx#6615
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Created comprehensive GitHub discussions for 7 archived issues - Updated all codebase references to point to discussions instead of issues - Each discussion is clearly marked as AI-generated and includes: - Complete summary of original issue and discussion thread - Key discussion points and technical details - Resolution status and workarounds - Links to related documentation Migrated issues: - #3451 (PowerShell support) → discussion #6733 - #1448 (env._.run) → discussion #6734 - #128 (plugin autoupdate) → discussion #6735 - #2961 (performance regression) → discussion #6736 - #1667 (go install) → discussion #6737 - #1196 (Java ls-remote) → discussion #6738 - #6615 (monorepo tasks) → discussion #6739 Updated files: - docs/faq.md - docs/environments/index.md - docs/configuration.md - e2e/cli/test_ls_cache - e2e/backend/test_go_install_slow - src/plugins/core/java.rs - e2e/tasks/test_task_monorepo_run_project_tasks 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
## Summary This PR migrates all jdx/mise issue links in the codebase to GitHub discussions, as issues are being disabled in favor of discussions for better community engagement. ## Changes ### Created GitHub Discussions Created comprehensive AI-generated summaries for 7 archived issues: 1. **#3451 (PowerShell support)** → [Discussion #6733](#6733) 2. **#1448 (env._.run)** → [Discussion #6734](#6734) 3. **#128 (plugin autoupdate)** → [Discussion #6735](#6735) 4. **#2961 (performance regression)** → [Discussion #6736](#6736) 5. **#1667 (go install)** → [Discussion #6737](#6737) 6. **#1196 (Java ls-remote)** → [Discussion #6738](#6738) 7. **#6615 (monorepo tasks)** → [Discussion #6739](#6739) Each discussion includes: - 🤖 Clear AI-generated labeling - Complete summary of original issue and discussion thread - Key discussion points and technical details - Resolution status and workarounds - Links to related documentation ### Updated Files - `docs/faq.md` - PowerShell support link - `docs/environments/index.md` - env._.run shebang link - `docs/configuration.md` - Plugin autoupdate link - `e2e/cli/test_ls_cache` - Performance issue reference - `e2e/backend/test_go_install_slow` - Go install issue reference - `src/plugins/core/java.rs` - Java version listing comment - `e2e/tasks/test_task_monorepo_run_project_tasks` - Monorepo task regression test reference ## Why With issues being disabled, these links would become dead. By creating comprehensive discussion summaries and updating the links, we: - Preserve historical context and knowledge - Maintain working references in documentation and code - Provide a better resource for users encountering similar issues - Support the migration to discussions-based community engagement ## Test plan - ✅ All links verified to point to created discussions - ✅ Discussions contain comprehensive summaries of original issue threads - ✅ Pre-commit hooks passed (shfmt, shellcheck, prettier, cargo check, taplo) 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Replaces GitHub issue references with discussion links across docs, e2e tests, and a Java plugin comment. > > - **Docs**: > - Update links from `issues` to `discussions` in `docs/configuration.md`, `docs/environments/index.md`, and `docs/faq.md`. > - **Tests (e2e)**: > - Replace issue references with discussions in `e2e/backend/test_go_install_slow`, `e2e/cli/test_ls_cache`, and `e2e/tasks/test_task_monorepo_run_project_tasks`. > - **Code**: > - Update comment link in `src/plugins/core/java.rs` (`_list_remote_versions`). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 0f526a3. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: Claude <noreply@anthropic.com>
Summary
Problem
When running mise commands with output redirection or in non-terminal environments (e.g., e2e tests, CI pipelines), OSC 9;4 escape sequences for terminal progress indicators were being written to stderr, causing visible escape codes like
]9;4;1;0to appear in the output.This was particularly noticeable in test output where you'd see:
(with the escape codes rendered as garbled characters)
Root Cause
The
write_progress()function insrc/ui/osc.rswas unconditionally writing OSC 9;4 sequences to stderr without checking if stderr was actually connected to a terminal.Solution
Added a check using
console::user_attended_stderr()to only write OSC sequences when stderr is an actual terminal. This ensures escape codes only appear in interactive terminal sessions where they're properly rendered.Test plan
🤖 Generated with Claude Code
Note
Guard OSC 9;4 progress writes behind a terminal check so escape sequences aren’t emitted to non-TTY stderr.
src/ui/osc.rs):console::user_attended_stderr()guard inwrite_progressto only write OSC 9;4 sequences whenstderris a terminal.Written by Cursor Bugbot for commit d0cb3c4. This will update automatically on new commits. Configure here.