Skip to content

Add mise extension - #31238

Draft
lachieh wants to merge 4 commits into
raycast:mainfrom
lachieh:ext/mise
Draft

lachieh wants to merge 4 commits into
raycast:mainfrom
lachieh:ext/mise

Conversation

@lachieh

@lachieh lachieh commented Sep 17, 2026 •

Copy link
Copy Markdown

Description

Raycast commands for mise (mise-en-place), the dev-tool version manager by @jdx

  • Search Tools — mise's registry plus npm:, cargo: and gem: package search; installs go to your global config (mise use -g, or a chosen config file).
  • Show Installed Tools — versions, active version, source file; set the global version, upgrade, uninstall.
  • Show Outdated Tools / Tools Menu Bar — what mise outdated reports, with one-click upgrades; the menu bar refreshes every 12 hours.
  • Upgrade All Tools, Prune Unused Versions, Clear Cache — the corresponding mise commands with progress toasts.
  • Manage Tasks — global mise tasks, run in your terminal or with captured output.

All commands operate on global mise configuration, which is what applies when Raycast has no project directory. mise itself is not bundled: the extension finds the user's binary (preference, standard paths, or their login shell) and runs it with the login shell's environment so exports like CARGO_HOME apply as they do in a terminal. Nothing is downloaded or executed with a shell; every mise call is execFile/spawn with an argument array.

Notes for review

  • npm run lint runs oxlint and oxfmt (the repository's day-to-day tooling); @raycast/eslint-config and Prettier are installed with Raycast's standard settings, and npx ray lint passes (ESLint and Prettier both run) — it is simply not wired into the npm scripts.
  • Tests: npm test (unit + component tests behind a small @raycast/api stub) and npm run test:integration (dry-runs every mise command line against a real mise).
  • Screenshots pass scripts/check_raycast_images.py and scripts/check_metadata_images.py locally.

Screencast

Screenshots of each command are in metadata/ (Search Tools with a backend query, Show Installed Tools with details, Show Outdated Tools, Manage Tasks, the version picker).

Checklist

- Refer to the Mise Path preference by its new title
- Name commands and preferences the way the store reads them
- Show a load error with Retry when a mise list fails
- Trim the changelog, identify mise in the README, and keep .agents local
- Recapture store screenshots at the enforcer\'s padding
- Format .oxlintrc.json
- Keep ray lint out of the package scripts
- Add Raycast\'s ESLint config and Prettier alongside oxlint and oxfmt
- Run Raycast\'s ESLint rules through oxlint
- Add store screenshots and shorten the Search Tools placeholder
- Rename the menu-bar command to Tools Menu Bar
- Run every mise call with the login shell\'s environment
- Run terminal hand-offs in an interactive login shell
- Add Manage Tasks
- Add a Terminal Application preference and Run in Terminal on installs
- Add preferences for upgrade flags, unuse, jobs, window and logging
- Give the operation factories flag options and exec a command observer
- Add component tests for the Raycast layer behind hand-written stubs
- Add an integration suite that dry-runs every operation against mise
- Show the requested version only when it is pinned
- Add Upgrade All Tools, Prune Unused Versions and Clear Cache
- Replace Check Outdated Tools with a Show Outdated Tools view
- Open deeplinks in Raycast by bundle id
- Add Check Outdated Tools for hosts without a menu bar
- Let installs choose the global config file
- Seed Search Tools from the deeplink fallbackText
- Add backend-prefixed queries to Search Tools
- Rename the extension icon to mise.png
- Prepare the extension for the Raycast store
- Run mise from the home directory
- Add Outdated Tools menu bar with per-tool and Upgrade All hand-off
- Add Installed Tools with set-global, upgrade and uninstall
- Rename useGlobally to addGlobally
- Replace no-op Search Tools with a registry view
- Add mise core with locate, exec, and parsers
- Add keyboard driving to verify-mise
- Make the sandbox note in verify-mise conditional
- Add verify-mise verification skill
- Replace eslint and prettier with oxlint and oxfmt
- Scaffold Raycast extension
@raycastbot raycastbot added new extension Label for PRs with new extensions platform: macOS labels Sep 17, 2026
@raycastbot

Copy link
Copy Markdown
Collaborator

Congratulations on your new Raycast extension! 🚀

We're currently experiencing a high volume of incoming requests. As a result, the initial review may take up to 15 business days.

Once the PR is approved and merged, the extension will be available on our Store.

@greptile-apps

greptile-apps Bot commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 4/5

The PR is not safe to merge until the open remove flow is fixed.

Findings

  1. P1 This import points to src/ui/useDebounced , but that file is not in the branch, so Search Tools cannot compile. The new operations.test.ts also reads fixtures/use-low-downloads-stderr.txt , which is missing. Add both files or remove these references before merging. ▶
  2. P1 remove runs unuse first and only runs uninstall --all after success. The installed list keeps tools with no active config, and Search Tools still gives those rows this Remove action. For such a tool, unuse fails because there is no config entry, so the runner stops before deleting any installed version. Skip unuse when no config declares the tool, or still run the uninstall step for that specific failure. ▶
Fix with agent prompt
### Issue 1
extensions/mise/src/search-tools.tsx:undefined-19
This import points to `src/ui/useDebounced`, but that file is not in the branch, so `Search Tools` cannot compile. The new `operations.test.ts` also reads `fixtures/use-low-downloads-stderr.txt`, which is missing. Add both files or remove these references before merging.

### Issue 2
extensions/mise/src/mise/operations.ts:93-94
`remove` runs `unuse` first and only runs `uninstall --all` after success. The installed list keeps tools with no active config, and `Search Tools` still gives those rows this Remove action. For such a tool, `unuse` fails because there is no config entry, so the runner stops before deleting any installed version. Skip `unuse` when no config declares the tool, or still run the uninstall step for that specific failure.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

Adds a macOS Raycast extension for managing mise tools and global tasks. It finds mise through preferences, common paths, or the login shell, then runs mise commands without a shell while supporting search, installs, upgrades, cleanup, outdated checks, and task output.

Reviews (4) · Last reviewed commit: "Add the debounce hook and low-downloads ..."

Comment thread extensions/mise/src/outdated-tools.tsx Outdated
Comment thread extensions/mise/src/search-tools.tsx
@socket-security

socket-security Bot commented Sep 17, 2026 •

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​@​types/​react-test-renderer@​19.0.01001007080100
Addednpm/​vitest@​5.0.1981007999100
Addednpm/​react-test-renderer@​19.0.0801008698100
Addednpm/​oxfmt@​0.68.0861008896100
Addednpm/​oxlint@​1.83.0991009196100

View full report

…h text

Addresses the two review findings: the menu bar showed "All tools up to
date" when mise outdated failed, and Search Tools seeded its backend
query from fallbackText without passing searchText to List.
@lachieh
lachieh marked this pull request as ready for review September 17, 2026 17:04
… Remove, and offer a low-downloads retry

- Search Tools filters and ranks the registry itself (capped), debounces
  the backend request and aborts in-flight searches when the query changes.
- Installed rows in Search Tools get a confirmed Remove (unuse, then
  uninstall --all) as their primary action.
- When mise refuses an npm package for low weekly downloads, the failure
  toast offers to retry with allow_low_downloads=true.
Comment thread extensions/mise/src/search-tools.tsx
Comment thread extensions/mise/src/mise/operations.ts
…s commit

The previous commit staged only modified files, so src/ui/useDebounced.ts
and the use-low-downloads-stderr fixture were left out and the build
could not resolve ./ui/useDebounced.

@0xdhrv 0xdhrv left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hey @lachieh 👋

Thanks for your contribution 🔥 This is a really thorough mise client — careful execFile/spawn usage, login-shell env probing, solid prefs, and a serious test suite.

Here's everything I found in this pass:

Blocking

  • issue (blocking): In Search Tools, Remove always runs mise unuse <tool> and only then mise uninstall --all <tool> (remove + runOperation's andThen). Installed tools with no config entry (inactive) make unuse fail, so uninstall never runs and nothing is deleted.

Please either:

  • only offer Remove when a version has a config source, and use uninstall-only for inactive tools, or

  • change remove so uninstall still runs when unuse fails because there is no config entry

  • issue (blocking): metadata/mise-3.png shows personal paths under /Users/lachlan/…. Please retake it with the Capture Window command (tick Save to Metadata) using mock data so the home directory isn’t identifiable.

Docs: https://developers.raycast.com/basics/prepare-an-extension-for-store#screenshots

Should fix

  • issue: In outdated-tools.tsx, launchCommand for Show Outdated Tools isn’t wrapped. It can throw if that command is disabled. Please catch it:
try {
  await launchCommand({ name: "show-outdated", type: LaunchType.UserInitiated, context: upgrade ? { upgrade } : undefined });
} catch (error) {
  await showFailureToast(error, { title: "Could not open Show Outdated Tools" });
}

Optional

  • suggestion: You can simplify some failure toasts with showFailureToast(error) from @raycast/utils (e.g. in runInTerminal / generic failure paths).

When the blocking items are done, press Ready for review. I've converted the PR to a draft until then 😊

Feel free to reach me here or on Slack if anything is unclear.

@0xdhrv
0xdhrv marked this pull request as draft September 30, 2026 08:14
@0xdhrv 0xdhrv self-assigned this Sep 30, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

new extension Label for PRs with new extensions platform: macOS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants