Skip to content

Script scanning

Buttons reads your project’s script files and turns each discovered script into a runnable command. It never writes to those files — it only reads them and stores references in .buttons.json.

The Buttons: Script Files setting controls which files are scanned. package.json is included by default; the others are opt-in checkboxes:

File Ecosystem Parsed as
package.json Node.js / TypeScript The scripts object.
Makefile C/C++, Go, generic Top-level targets (name:).
composer.json PHP The scripts object, run with composer <name>.
justfile Universal task runner Recipes (name:), excluding private _-prefixed recipes.

For package.json, the script body (and for Makefile/justfile, a preceding # comment) is captured as a description shown with the button.

Only these formats are parsed. Other ecosystems (Python pyproject.toml, Rust Cargo.toml, .NET, and so on) aren’t auto-parsed — add their commands as custom commands instead.

Disabling a file type stops offering its scripts in the Project scripts tab, but never removes buttons already in your .buttons.json.

The runner used for package.json scripts is detected from the root lockfiles, in this order:

Lockfile Package manager
pnpm-lock.yaml pnpm
yarn.lock yarn
bun.lockb bun
package-lock.json npm

If none is found, it defaults to npm. The detected manager applies to all package.json files in the workspace (monorepos are assumed to use one manager). Because script entries are references, switching lockfiles and rescanning updates every command automatically — npm run dev becomes pnpm dev, and so on.

Makefile, composer.json, and justfile targets always use their fixed runner (make, composer, just) regardless of the detected package manager.

Two related but distinct actions:

  • Generate — creates the project’s .buttons.json from scratch with every discovered script. It only appears when no project file exists yet. Use it the first time you open a project.
  • Rescan — re-runs the scanner against the existing file. It:
    • keeps your included scripts and notes,
    • recomputes their commands (for example after a package-manager change),
    • marks scripts that no longer exist as not found,
    • leaves newly-discovered scripts unchecked for you to opt in,
    • never touches custom command entries.

In short: Generate seeds the file; Rescan updates it in place without overriding your custom commands or selections.

In the Project scripts tab, check or uncheck scripts to include or remove them as buttons. Changes are saved immediately once the file exists.

These directories are never scanned (installed packages, VCS, and build/cache output):

node_modules, .git, .hg, .svn, .next, .nuxt, .output, .cache, .turbo, .yarn, .pnpm-store, dist, build, out, coverage, vendor, .venv, venv, __pycache__, .vscode, .idea, target, .svelte-kit, .parcel-cache

In addition, any hidden (dot-prefixed) directory is skipped. The scan is capped at 5000 matching files.