Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ The mise-vscode extension integrates mise's core functionality into VS Code, hel
- 🧩 Autocompletion & hover for [task arguments](https://mise.jdx.dev/tasks/task-arguments.html)
(`usage` field, `#USAGE`/`#MISE` comments in file tasks, `$usage_*` variables)
- 🔗 Go to definition, find references for mise tasks
- 🪄 Syntax highlighting for extensionless
[tool stub](https://mise.jdx.dev/dev-tools/tool-stubs.html) files

### [Task Management](https://hverlin.github.io/mise-vscode/reference/tasks/)

Expand Down
45 changes: 41 additions & 4 deletions pnpm-lock.yaml → aube-lock.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ importers:
version: 1.4.6(@rsbuild/core@1.7.6)
'@std/collections':
specifier: jsr:^1.1.7
version: '@jsr/std__collections@1.3.0'
version: 1.3.0
'@tanstack/match-sorter-utils':
specifier: ^8.19.4
version: 8.19.4
Expand Down Expand Up @@ -1186,6 +1186,10 @@ packages:
'@sinonjs/samsam@10.0.2':
resolution: {integrity: sha512-8lVwD1Df1BmzoaOLhMcGGcz/Jyr5QY2KSB75/YK1QgKzoabTeLdIVyhXNZK9ojfSKSdirbXqdbsXXqP9/Ve8+A==}

'@std/collections@1.3.0':
resolution: {integrity: sha512-oJ5V5ZvsWyO5VLdGk3TaRHaVibfVKHvDC8KJdgmxIucHN2QzAXlMt36ApyTUBncfrhXdN/5Q3yMNvloAKym8RA==, tarball: https://npm.jsr.io/~/11/@jsr/std__collections/1.3.0.tgz}
aliasOf: '@jsr/std__collections'

'@swc/helpers@0.5.23':
resolution: {integrity: sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==}

Expand Down Expand Up @@ -3342,6 +3346,11 @@ packages:
stream-replace-string@2.0.0:
resolution: {integrity: sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==}

string-width-cjs@4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
aliasOf: string-width

string-width@4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
Expand All @@ -3367,6 +3376,11 @@ packages:
stringify-entities@4.0.4:
resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==}

strip-ansi-cjs@6.0.1:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
engines: {node: '>=8'}
aliasOf: strip-ansi

strip-ansi@6.0.1:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
engines: {node: '>=8'}
Expand Down Expand Up @@ -3713,6 +3727,11 @@ packages:
workerpool@9.3.4:
resolution: {integrity: sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg==}

wrap-ansi-cjs@7.0.0:
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
engines: {node: '>=10'}
aliasOf: wrap-ansi

wrap-ansi@7.0.0:
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
engines: {node: '>=10'}
Expand Down Expand Up @@ -4358,11 +4377,11 @@ snapshots:
'@isaacs/cliui@8.0.2':
dependencies:
string-width: 5.1.2
string-width-cjs: string-width@4.2.3
string-width-cjs: 4.2.3
strip-ansi: 7.2.0
strip-ansi-cjs: strip-ansi@6.0.1
strip-ansi-cjs: 6.0.1
wrap-ansi: 8.1.0
wrap-ansi-cjs: wrap-ansi@7.0.0
wrap-ansi-cjs: 7.0.0

'@istanbuljs/schema@0.1.6': {}

Expand Down Expand Up @@ -4716,6 +4735,8 @@ snapshots:
'@sinonjs/commons': 3.0.1
type-detect: 4.1.0

'@std/collections@1.3.0': {}

'@swc/helpers@0.5.23':
dependencies:
tslib: 2.8.1
Expand Down Expand Up @@ -7564,6 +7585,12 @@ snapshots:

stream-replace-string@2.0.0: {}

string-width-cjs@4.2.3:
dependencies:
emoji-regex: 8.0.0
is-fullwidth-code-point: 3.0.0
strip-ansi: 6.0.1

string-width@4.2.3:
dependencies:
emoji-regex: 8.0.0
Expand Down Expand Up @@ -7600,6 +7627,10 @@ snapshots:
character-entities-html4: 2.1.0
character-entities-legacy: 3.0.0

strip-ansi-cjs@6.0.1:
dependencies:
ansi-regex: 5.0.1

strip-ansi@6.0.1:
dependencies:
ansi-regex: 5.0.1
Expand Down Expand Up @@ -7906,6 +7937,12 @@ snapshots:

workerpool@9.3.4: {}

wrap-ansi-cjs@7.0.0:
dependencies:
ansi-styles: 4.3.0
string-width: 4.2.3
strip-ansi: 6.0.1

wrap-ansi@7.0.0:
dependencies:
ansi-styles: 4.3.0
Expand Down
17 changes: 17 additions & 0 deletions docs/src/content/docs/reference/mise.toml-language-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,23 @@ In `.tool-versions` files, backend prefixes (`core:`, `npm:`, `cargo:`, ...) are
also autocompleted, and typing a prefix such as `core:` suggests the registry
tools of that backend (e.g. `core:node`).

### Tool stubs

[Tool stubs](https://mise.jdx.dev/dev-tools/tool-stubs.html) are executable
files (usually committed under `bin/`) whose body is TOML under a
`#!/usr/bin/env -S mise tool-stub` shebang:

```toml
#!/usr/bin/env -S mise tool-stub

version = "2.96.0"
tool = "github:cli/cli"
bin = "bin/gh"
```

The extension detects the shebang and opens stub files as TOML, so they get
syntax highlighting even though they have no `.toml` extension.

#### Autocompletion for tasks

Code completion is provided for `depends = ["task_name"]`, `depends_post = ["task_name"]`, `wait_for = ["task_name"]`.
Expand Down
105 changes: 47 additions & 58 deletions mise.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
[tools]
pkl = "0.29.1"
node = '24'
node = "24"
hk = "1.18.1"
aube = "1.37.0"
bun = "1.3.14"

[settings]
lockfile = true
experimental = true

[deps.aube]
auto = true

[env]
_.path = ["./node_modules/.bin"]
Expand All @@ -15,112 +19,97 @@ CODE_CMD = "code"
### Main tasks

[tasks.dev]
description = 'Starts the project in watch mode and opens the extension in VSCode'
depends = ['dev-extension', 'dev-webviews', 'start-vscode']
description = "Starts the project in watch mode and opens the extension in VSCode"
depends = ["dev-extension", "dev-webviews", "start-vscode"]

[tasks.dev-web]
description = 'Starts the project in watch mode and opens the extension in VSCode Web'
depends = ['dev-extension-web', 'dev-webviews', 'start-vscode-web']
description = "Starts the project in watch mode and opens the extension in VSCode Web"
depends = ["dev-extension-web", "dev-webviews", "start-vscode-web"]

[tasks.check]
description = "Lint, type-check, and test the project"
depends = ['lint-fix', 'test', 'ts-check', 'docs:extractSettings']
depends = ["lint-fix", "test", "ts-check", "docs:extractSettings"]

[tasks.check-all]
description = "Lint, type-check, test, build docs, and run e2e tests"
depends = ['lint-fix', 'test', 'ts-check', 'docs:extractSettings', 'docs:build', 'e2e-tests']
depends = ["check", "docs:build", "e2e-tests"] # Simplified by nesting 'check'

#####################

[tasks."docs:extractSettings"]
run = 'bun src/extract-settings.mjs'
run = "bun src/extract-settings.mjs"
dir = "{{config_root}}/docs"

[tasks."docs:dev"]
alias = 'docs'
description = 'Builds the documentation'
run = 'exec node --run dev'
alias = "docs"
description = "Builds the documentation"
run = "exec node --run dev"
dir = "{{config_root}}/docs"
depends = ['docs:extractSettings', 'install']
depends = ["docs:extractSettings"] # 'aube' auto-runs if needed via deps

[tasks."docs:build"]
run = 'node --run build'
run = "node --run build"
dir = "{{config_root}}/docs"

[tasks."docs:preview"]
run = 'node --run preview'
run = "node --run preview"
dir = "{{config_root}}/docs"
depends = ['docs:build']

[tasks.install]
description = 'Installs dependencies with aube'
run = 'aube install'
depends = ["docs:build"]

[tasks.start-vscode]
description = 'Starts VSCode with the extension loaded'
run = '$CODE_CMD --inspect-extensions=5858 --extensionDevelopmentPath={{cwd}}'
wait_for = ['install']
description = "Starts VSCode with the extension loaded"
run = "$CODE_CMD --inspect-extensions=5858 --extensionDevelopmentPath={{cwd}}"

[tasks.start-vscode-web]
description = 'Starts VSCode Web with the extension loaded'
run = 'npx @vscode/test-web --extensionDevelopmentPath={{cwd}}'
wait_for = ['install']
description = "Starts VSCode Web with the extension loaded"
run = "npx @vscode/test-web --extensionDevelopmentPath={{cwd}}"

[tasks.watch-vscode]
run = 'mise watch -t start-vscode'
run = "mise watch -t start-vscode"

[tasks.start-vscode-inspect-brk]
description = 'Starts VSCode with the extension loaded. Pauses on the first line of the extension'
run = '$CODE_CMD --inspect-brk-extensions=5858 --extensionDevelopmentPath={{cwd}}'
description = "Starts VSCode with the extension loaded. Pauses on the first line of the extension"
run = "$CODE_CMD --inspect-brk-extensions=5858 --extensionDevelopmentPath={{cwd}}"

[tasks.dev-extension]
depends = ['install']
description = 'Builds the project in watch mode'
run = 'rsbuild dev'
description = "Builds the project in watch mode"
run = "rsbuild dev"

[tasks.dev-extension-web]
depends = ['install']
description = 'Builds the project for VSCode Web in watch mode'
run = 'rslib build -c rslib.browser.config.ts --watch --config-loader jiti'
description = "Builds the project for VSCode Web in watch mode"
run = "rslib build -c rslib.browser.config.ts --watch --config-loader jiti"

[tasks.dev-webviews]
description = 'Render webviews in watch mode.'
run = 'node --run dev-webviews'
depends = ['install']
description = "Render webviews in watch mode."
run = "node --run dev-webviews"

[tasks.dev-reload-vscode]
description = 'Starts the project in watch mode and opens the extension in VSCode. Reload VSCode on changes'
depends = ['dev-extension', 'dev-webviews', 'watch-vscode']
description = "Starts the project in watch mode and opens the extension in VSCode. Reload VSCode on changes"
depends = ["dev-extension", "dev-webviews", "watch-vscode"]

[tasks.ts-check]
description = 'Type-check the project'
depends = ['install']
run = 'hk check --step tsc -a'
description = "Type-check the project"
run = "hk check --step tsc -a"

[tasks.biome-lint]
description = 'Lint the project with biome'
depends = ['install']
run = 'hk check --step biome -a'
description = "Lint the project with biome"
run = "hk check --step biome -a"

[tasks.lint]
description = 'Lint the project + type-check'
depends = ['install']
run = 'hk check'
description = "Lint the project + type-check"
run = "hk check"

[tasks.lint-fix]
description = 'Lint the project + type-check and fix issues'
depends = ['install']
run = 'hk fix'
description = "Lint the project + type-check and fix issues"
run = "hk fix"

[tasks.test]
description = 'Run tests'
depends = ['install']
run = 'node --run test'
description = "Run tests"
run = "node --run test"

[tasks.e2e-tests]
run = 'node --run e2e-tests'
depends = ['install']
run = "node --run e2e-tests"

[tasks.e2e-test-action]
tools = { act = 'latest' }
run = 'act push -j e2e-tests'
tools = { act = "latest" }
run = "act push -j e2e-tests"
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
"filenamePatterns": [
"mise.*.lock"
],
"firstLine": "^#!\\s*/usr/bin/env\\s+(-S\\s+)?mise\\s+tool-stub\\b",
"configuration": "./syntaxes/toml-language-configuration.json"
},
{
Expand Down
6 changes: 6 additions & 0 deletions src/e2e-tests/fixtures/task-execution-workspace/stubs/gh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env -S mise tool-stub
# GitHub CLI pinned for this repo

version = "2.96.0"
tool = "github:cli/cli"
bin = "bin/gh"
24 changes: 24 additions & 0 deletions src/e2e-tests/tool-stub.e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import * as assert from "node:assert";
import * as path from "node:path";
import * as vscode from "vscode";

/**
* Verifies that a mise tool stub (https://mise.jdx.dev/dev-tools/tool-stubs.html)
* opens as TOML through the `firstLine` language association contributed in
* package.json, even though the file has no extension.
* The fixture lives in `stubs/` (not the conventional `bin/`) because the
* relative-bin-path and workspace-binary-approval suites wipe `bin/`.
*/
suite("Tool Stub Test Suite", function () {
this.timeout(30_000);

test("opens extensionless stubs as TOML via the shebang", async () => {
const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;
assert.ok(workspaceRoot, "Workspace root should be available");

const document = await vscode.workspace.openTextDocument(
path.join(workspaceRoot, "stubs", "gh"),
);
assert.equal(document.languageId, "toml");
});
});