Fix task/tasks skill: fast single-call lookup, run, and create-offer#33
Merged
Conversation
skapoor8
commented
Jul 19, 2026
skapoor8
left a comment
Contributor
Author
There was a problem hiding this comment.
Automated review: 7 inline comments (3 BLOCKING run-path bugs). See details inline.
skapoor8
added a commit
that referenced
this pull request
Jul 19, 2026
Model-driven dispatch (SKILL.md -> detect.md -> list.md -> run.md) made `/task detect` and `/task list` take ~2 minutes: every verb walked several reference docs and ran ad-hoc bash the model assembled per call. Replace that hot path with one shipped POSIX-sh script so detection, listing, running, and the no-match offer happen in a single deterministic process. **Single shipped dispatcher** - Add scripts/task.sh: one source of truth for runner detection (mise -> just -> Taskfile -> package.json -> none), listing, and running. - No argument lists tasks; an unrecognised first token is treated as a run query and matched against the runner's task names; a query with no match returns NO_MATCH so the skill can offer to create a runner-native task entry instead of failing. - SKILL.md maps every verb to a single Bash call; the three workflow docs shrink to thin references pointing at the script, so no executable bash remains on the hot path. **Correct lookup signals** - List names via `mise tasks ls --no-header` so the first task is no longer dropped by a header-skipping awk (mise 2026.3.x emits no header); dropping it made `/task <first>` wrongly offer to create an existing task. - Capture enumeration stderr: a runner present but unable to enumerate (e.g. untrusted mise on a fresh clone) is reported as ENUM_FAILED, surfacing the trust error rather than offering to create the task. - Two or more prefix/substring candidates return AMBIGUOUS with the candidate list so the query is disambiguated, not treated as no-match. - Match literally via `grep -F` and a lowercased case-glob prefix; the query is never interpreted as a regex. **/tasks alias with a drift guard** - Ship skills/tasks/ as a generated mirror of canonical skills/task/ (identical but for the name, `/tasks` trigger token, and SKILL.md H1), so both triggers share the same fast script. - Add .mise-tasks/gen-task-alias to regenerate it and a skills:sync-task-alias task; fold a --check drift guard (content and exec-bit modes) into skills:validate so CI fails if the two diverge. - Update docs/skills/task.md for no-arg list, bare-query run, and the create-offer. Closes #33
skapoor8
force-pushed
the
fix/task-speedup
branch
from
July 19, 2026 19:35
dd86f91 to
3d1459e
Compare
Model-driven dispatch (SKILL.md -> detect.md -> list.md -> run.md) made `/task detect` and `/task list` take ~2 minutes: every verb walked several reference docs and ran ad-hoc bash the model assembled per call. Replace that hot path with one shipped POSIX-sh script so detection, listing, running, and the no-match offer happen in a single deterministic process. **Single shipped dispatcher** - Add scripts/task.sh: one source of truth for runner detection (mise -> just -> Taskfile -> package.json -> none), listing, and running. - No argument lists tasks; an unrecognised first token is treated as a run query and matched against the runner's task names; a query with no match returns NO_MATCH so the skill can offer to create a runner-native task entry instead of failing. - SKILL.md maps every verb to a single Bash call; the three workflow docs shrink to thin references pointing at the script, so no executable bash remains on the hot path. **Correct lookup signals** - List names via `mise tasks ls --no-header` so the first task is no longer dropped by a header-skipping awk (mise 2026.3.x emits no header); dropping it made `/task <first>` wrongly offer to create an existing task. - Capture enumeration stderr: a runner present but unable to enumerate (e.g. untrusted mise on a fresh clone) is reported as ENUM_FAILED, surfacing the trust error rather than offering to create the task. - Two or more prefix/substring candidates return AMBIGUOUS with the candidate list so the query is disambiguated, not treated as no-match. - Match literally via `grep -F` and a lowercased case-glob prefix; the query is never interpreted as a regex. **/tasks alias with a drift guard** - Ship skills/tasks/ as a generated mirror of canonical skills/task/ (identical but for the name, `/tasks` trigger token, and SKILL.md H1), so both triggers share the same fast script. - Add .mise-tasks/gen-task-alias to regenerate it and a skills:sync-task-alias task; fold a --check drift guard (content and exec-bit modes) into skills:validate so CI fails if the two diverge. - Update docs/skills/task.md for no-arg list, bare-query run, and the create-offer. Closes #33
skapoor8
force-pushed
the
fix/task-speedup
branch
from
July 19, 2026 19:40
3d1459e to
d56c89f
Compare
skapoor8
marked this pull request as ready for review
July 19, 2026 19:41
github-actions Bot
pushed a commit
that referenced
this pull request
Jul 19, 2026
## [1.66.1](v1.66.0...v1.66.1) (2026-07-19) ### Performance Improvements * **task:** deterministic single-script runner dispatch + /tasks alias ([#33](#33)) Model-driven dispatch (SKILL.md -> detect.md -> list.md -> run.md) made `/task detect` and `/task list` take ~2 minutes: every verb walked several reference docs and ran ad-hoc bash the model assembled per call. Replace that hot path with one shipped POSIX-sh script so detection, listing, running, and the no-match offer happen in a single deterministic process. **Single shipped dispatcher** - Add scripts/task.sh: one source of truth for runner detection (mise -> just -> Taskfile -> package.json -> none), listing, and running. - No argument lists tasks; an unrecognised first token is treated as a run query and matched against the runner's task names; a query with no match returns NO_MATCH so the skill can offer to create a runner-native task entry instead of failing. - SKILL.md maps every verb to a single Bash call; the three workflow docs shrink to thin references pointing at the script, so no executable bash remains on the hot path. **Correct lookup signals** - List names via `mise tasks ls --no-header` so the first task is no longer dropped by a header-skipping awk (mise 2026.3.x emits no header); dropping it made `/task <first>` wrongly offer to create an existing task. - Capture enumeration stderr: a runner present but unable to enumerate (e.g. untrusted mise on a fresh clone) is reported as ENUM_FAILED, surfacing the trust error rather than offering to create the task. - Two or more prefix/substring candidates return AMBIGUOUS with the candidate list so the query is disambiguated, not treated as no-match. - Match literally via `grep -F` and a lowercased case-glob prefix; the query is never interpreted as a regex. **/tasks alias with a drift guard** - Ship skills/tasks/ as a generated mirror of canonical skills/task/ (identical but for the name, `/tasks` trigger token, and SKILL.md H1), so both triggers share the same fast script. - Add .mise-tasks/gen-task-alias to regenerate it and a skills:sync-task-alias task; fold a --check drift guard (content and exec-bit modes) into skills:validate so CI fails if the two diverge. - Update docs/skills/task.md for no-arg list, bare-query run, and the create-offer. Closes #33
|
🎉 This PR is included in version 1.66.1 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
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.
Intent
Make
/task(and its/tasksalias) fast. This skill sits on a hot path — the spec, em, dev, and gcp skills all call/task detect//task listbefore running any build/test/lint. Each call was taking ~2 minutes for a job that is really ~1ms of shell. This branch collapses that into a single deterministic script call, and makes no-arg invocations list tasks, query invocations run the matching task, and unmatched queries offer to create a runner-native task.Bug
Detecting the project's task runner took ~2 minutes per
/taskcall. The detection work itself is trivial (a fewtest -fmarker checks plus onejqonpackage.json, ~1ms). The slowness was structural: the model did the work by transcribing-and-executing bash across four markdown files. SKILL.md dispatched toreferences/workflows/detect.md;list.mdre-inlined the same detection and its list command;run.mddid it a third time. Every "read this file, transcribe its bash, run it, read the output, move to the next file" hop is a slow LLM round-trip. Four files × round-trips = minutes for a millisecond job.Fix
Move the deterministic part into one shipped script and reduce the model's role to "run one command, read its output."
skills/task/scripts/task.sh— single POSIX-sh source of truth for detect/list/run and the no-match offer, one process per call:list→ detect runner, printRUNNER: <name>, then the task listing (or a no-runner message with amise.tomlsuggestion).detect→ runner name plus run/list commands in stableKEY=valueform.run <query> [args…]→ detect, resolve query (exact → unique prefix/substring),execthe runner on match; on no match, exit distinctly and print the task list plus aNO_MATCH:<query>marker.skills/task/SKILL.mdrewritten to a thin dispatcher: every verb maps to onebash scripts/task.sh …call. No-arg → list; an unrecognized first token →run <query>(so/task test,/task build --releasejust work); explicitdetect/list/runstill take precedence. OnNO_MATCH, it offers a runner-native entry (mise[tasks.*], just recipe,Taskfile.ymltask,package.jsonscript — or a scaffoldedmise.tomlif no runner), gated behind user confirmation.detect.md/list.md/run.mdthinned to short reference docs describing the script contract — no executable bash on the hot path./tasksalias reconciled and kept in sync:.mise-tasks/gen-task-aliasregeneratesskills/tasks/fromskills/task/(identical except thename/trigger token), wired viamise run skills:sync-task-aliaswith a drift--checkfolded intoskills:validate.docs/skills/task.mdupdated for the new behaviour.Detection order (mise → just → Taskfile → package.json → none) and cross-skill references (
/task detect,/task list,/tasks list) are unchanged — no other skill needs to change.Fixes:
Validation
mise run skills:validatepasses — 44/44 SKILL.md checks plus the alias drift--check/taskwith no args lists tasks in a single Bash call (no multi-file dispatch)/task <known-task>runs the matching runner command; extra args pass through/task <unknown>offers a runner-native create snippet for the detected runner/task detect|list|runverbs and aliases produce equivalent output