feat: add default_subcommand and restart_token for naked task completions#410
feat: add default_subcommand and restart_token for naked task completions#410
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds two new features to support "naked" task completion in mise: default_subcommand at the spec level and restart_token at the command level. The default_subcommand allows routing commands like mise foo to mise run foo when foo isn't a known subcommand. The restart_token enables multiple task invocations in a single command line (e.g., mise run lint ::: test ::: check) by resetting argument parsing at each token.
- Added
default_subcommandfield toSpecfor automatic subcommand routing - Added
restart_tokenfield toSpecCommandfor argument parsing resets - Updated parsing and completion logic to handle both features
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| lib/src/spec/mod.rs | Added default_subcommand field with parsing, serialization, and merge support |
| lib/src/spec/cmd.rs | Added restart_token field with parsing, serialization, and merge support |
| lib/src/spec/builder.rs | Added builder method for restart_token configuration |
| lib/src/parse.rs | Implemented parsing logic for both features and added comprehensive tests |
| cli/src/cli/complete_word.rs | Updated completion logic to support both features |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…ions
Adds two new features to support mise's naked task completion needs:
1. **default_subcommand** (Spec level): When the first non-flag argument
isn't a known subcommand, automatically route to the specified default
subcommand. This enables `mise foo` to work like `mise run foo`.
```kdl
default_subcommand "run"
```
2. **restart_token** (SpecCommand level): A token that resets argument
parsing, allowing multiple command invocations on one line. This
enables `mise run lint ::: test ::: check` to complete task names
after each `:::`.
```kdl
cmd run {
restart_token ":::"
}
```
Both features include:
- KDL parsing and serialization
- Integration with parse_partial for correct argument routing
- Integration with complete_word for shell completions
- Builder API support
- Comprehensive tests
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
675ee7b to
abb913b
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #410 +/- ##
==========================================
- Coverage 57.32% 52.08% -5.25%
==========================================
Files 47 47
Lines 5561 5894 +333
Branches 5561 5894 +333
==========================================
- Hits 3188 3070 -118
- Misses 1316 1438 +122
- Partials 1057 1386 +329 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
| next_arg = out.cmd.args.first(); | ||
| // Keep flags and continue parsing | ||
| continue; | ||
| } |
There was a problem hiding this comment.
restart_token doesn't reset enable_flags after -- separator
When encountering a restart_token, the enable_flags variable is not reset to true. If the user previously used -- to disable flag parsing (e.g., mise run task1 -- extra ::: --verbose task2), flags after the restart token will still be treated as positional arguments instead of flags. Since the restart token represents a new independent command invocation, enable_flags needs to be reset to true alongside the other state resets to allow proper flag parsing in subsequent invocations.
Fixed two bugs in restart_token handling:
1. Clear flag_awaiting_value when encountering restart_token
- Previously, if a flag expecting a value appeared before :::
(e.g., `mise run lint --jobs ::: test`), the word after :::
would be consumed as the flag's value instead of being parsed
as a new positional argument.
2. Reset enable_flags to true when encountering restart_token
- Previously, if -- was used before ::: to disable flag parsing
(e.g., `mise run task1 -- extra ::: --verbose task2`), flags
after ::: would still be treated as positional arguments.
Also fixed completion logic to check after_restart_token before
flag_awaiting_value, ensuring completions after ::: offer the
correct first argument completions.
Added tests for both edge cases.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
bugbot run |
Move after_restart_token check after flag completion checks so that typing `mise run lint ::: --<TAB>` correctly offers flag completions instead of trying to complete as a positional argument. The check order is now: 1. Flag completions (-, --, -x) 2. after_restart_token (first positional arg) 3. flag_awaiting_value 4. Normal arg/subcommand completion 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
## [2.11.0](https://github.com/jdx/usage/compare/v2.10.0..v2.11.0) - 2025-12-31 ### 🚀 Features - add default_subcommand and restart_token for naked task completions by [@jdx](https://github.com/jdx) in [#410](#410) ### 🐛 Bug Fixes - handle --help flag in exec command for non-shell scripts by [@jdx](https://github.com/jdx) in [#409](#409) ### 🧪 Testing - add non-shell script tests by [@muzimuzhi](https://github.com/muzimuzhi) in [#406](#406) ### 📦️ Dependency Updates - lock file maintenance by [@renovate[bot]](https://github.com/renovate[bot]) in [#403](#403) - lock file maintenance by [@renovate[bot]](https://github.com/renovate[bot]) in [#407](#407) - lock file maintenance by [@renovate[bot]](https://github.com/renovate[bot]) in [#408](#408)
## Summary Enables shell completions for: - **Naked task commands**: `mise foo <TAB>` now completes like `mise run foo <TAB>` - **Multi-task separators**: `mise run lint ::: <TAB>` now completes task names again after `:::` ## Changes - Add `default_subcommand = "run"` to the usage spec so unknown first args route to `run` - Add `restart_token = ":::"` to `run` and `tasks run` commands for multi-task completion - Bump `min_usage_version` from "1.3" to "2.11" - Update `task_script_parser.rs` with new `var_min`/`var_max` fields for usage-lib 2.11 compatibility ## Dependencies Requires usage-lib v2.11.0 (jdx/usage#410) ## Test plan - [ ] `mise fo<TAB>` completes task name "foo" (naked completion) - [ ] `mise run lint ::: te<TAB>` completes task name "test" (restart token) - [ ] `mise --verbose fo<TAB>` still works with global flags before naked arg 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds enhanced shell completions and updates the usage spec for compatibility. > > - Set `spec.default_subcommand = "run"` to enable naked task completions (`mise foo <TAB>` behaves like `mise run foo <TAB>`) > - Add `restart_token = ":::"` to `run` and `tasks run` for multi-task completions after `:::` > - Bump `min_usage_version` to `2.11` and update dependency to `usage-lib 2.11.0` > - Align parser with new spec by initializing `usage::SpecFlag` with `var_min`/`var_max` fields > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 536a529. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This MR contains the following updates: | Package | Update | Change | |---|---|---| | [usage](https://github.com/jdx/usage) | minor | `2.10.0` → `2.11.0` | MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot). **Proposed changes to behavior should be submitted there as MRs.** --- ### Release Notes <details> <summary>jdx/usage (usage)</summary> ### [`v2.11.0`](https://github.com/jdx/usage/blob/HEAD/CHANGELOG.md#2110---2025-12-31) [Compare Source](jdx/usage@v2.10.0...v2.11.0) ##### 🚀 Features - add default\_subcommand and restart\_token for naked task completions by [@​jdx](https://github.com/jdx) in [#​410](jdx/usage#410) ##### 🐛 Bug Fixes - handle --help flag in exec command for non-shell scripts by [@​jdx](https://github.com/jdx) in [#​409](jdx/usage#409) ##### 🧪 Testing - add non-shell script tests by [@​muzimuzhi](https://github.com/muzimuzhi) in [#​406](jdx/usage#406) ##### 📦️ Dependency Updates - lock file maintenance by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​403](jdx/usage#403) - lock file maintenance by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​407](jdx/usage#407) - lock file maintenance by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​408](jdx/usage#408) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this MR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box --- This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi42OS4yIiwidXBkYXRlZEluVmVyIjoiNDIuNjkuMiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiUmVub3ZhdGUgQm90IiwiYXV0b21hdGlvbjpib3QtYXV0aG9yZWQiLCJkZXBlbmRlbmN5LXR5cGU6Om1pbm9yIl19-->
Summary
Adds two new features to support mise's naked task completion needs:
default_subcommand(Spec level): When the first non-flag argument isn't a known subcommand, automatically route to the specified default subcommand. This enablesmise footo work likemise run foo.restart_token(SpecCommand level): A token that resets argument parsing, allowing multiple command invocations on one line. This enablesmise run lint ::: test ::: checkto complete task names after each:::.Changes
default_subcommandfield toSpecstruct with parsing, serialization, and merge supportrestart_tokenfield toSpecCommandstruct with parsing, serialization, and merge supportrestart_token()method toSpecCommandBuilderparse_partialto handle both features:default_subcommandand route accordinglyrestart_token, reset argument parsing statedefault_subcommand: also include completions from default subcommand's argsrestart_token: complete from first arg of current commandTest plan
test_default_subcommand- verifies naked command routingtest_default_subcommand_explicit_still_works- explicit subcommand takes precedencetest_restart_token- verifies argument parsing resettest_restart_token_multiple- multiple restart tokens in sequenceUsage in mise
After this lands, mise will configure:
This will enable:
mise lint→ completes task argumentsmise run lint ::: <TAB>→ completes task names again🤖 Generated with Claude Code
Note
Adds first-class support for naked subcommands and multi-invocation parsing.
spec.default_subcommandwhen first non-flag token isn’t a known subcommand; Phase 2 recognizescmd.restart_tokento reset arg parsing, pending flag values, and--statecomplete_wordnow completes from the default subcommand’s first arg at root and from the first arg after arestart_tokenSpec.default_subcommandandSpecCommand.restart_tokenfields with KDL parse/serialize andmergesupportSpecCommandBuilder::restart_token()Written by Cursor Bugbot for commit 43b9ad5. This will update automatically on new commits. Configure here.