mash up millions of open source packages into monstrously powerful scripts.
Caution
We have not vetted any of the scripts mash
can run and (currently) they
can do anything they want to your computer.
We fully intend to add sandboxing and user reporting, but you have found
mash
super early in its life so you must practice caution in your usage.
All scripts can be read in advance via mash.pkgx.sh
$ mash # or https://mash.pkgx.sh
# lists all script categories
You can browse script listings with the TUI or at mash.pkgx.sh:
$ mash ai # or https://mash.pkgx.sh/ai/
# lists all ai scripts
Note
The above lists all user submitted scripts in the ai
category.
Once you’ve found a script you want to run:
$ mash ai chat --help # or https://mash.pkgx.sh/ai/chat/
To install mash
and pkgx
:
curl https://mash.pkgx.sh | sh
# ^^ installs /usr/local/bin/mash and /usr/local/bin/pkgx
If you prefer, you can run mash
via pkgx
:
$ brew install pkgxdev/made/pkgx # or curl https://pkgx.sh | sh
$ pkgx mash
# or install it via pkgx:
$ pkgx install mash
$ mash
Tip
brew install pkgxdev/made/pkgx
; orcurl https://pkgx.sh | sh
; or- docs.pkgx.sh/getting-started
mash
is a plain POSIX script. All it needs is bash
, curl
, and pkgx
.
So if you like you can just download it by itself.
Note
Keeping mash so minimal isn’t a concrete design choice. We will entertain rewriting it in something better for dev as it gets more complicated.
In fact the minimalist nature of mash
is more a testament to pkgx
’s
powerful and composable packaging primitives.
Use any shell or scripting language you like. You specify it with the shebang:
#!/usr/bin/env -S pkgx ruby
Generally it is sensible to specify constrained versions:
#!/usr/bin/env -S pkgx [email protected]
mash
operates with a “categorization by default is good” philosophy. Your
scripts must be categorized or namespaced with your user.
Thus if you add a script named foo
it can only be used via
mash username/foo
. But if you add a script called foo-bar
if will be
listed if a user types mash foo
:
$ mash foo
mash foo bar # your description about `foo bar` is shown here
mash foo other-script # …
Tip
Extensions (eg. .sh
, .ts
) are recommended for GitHub readability.
They will be stripped from the mash execution name, eg. foo-bar.ts
is
invoked via mash foo bar
and not mash foo bar.ts
Many languages or interpreters nowadays provide clear methods for importing
language dependencies inside scripts, eg. deno
, or bun
. For other
languages, read on.
Use Bundler:
#!/usr/bin/env -S pkgx ruby@3
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'ruby-macho', '~> 3'
end
Typically for everything else, use scriptisto
, eg for Python:
#!/usr/bin/env -S pkgx [email protected] +virtualenv scriptisto
# snip… type `scriptisto new python-pip` for the rest.
Use scriptisto new
for a full listing of platforms Scriptisto makes
available.
- Fork pkgxdev/mash
- Add scripts to
./scripts/
- Optionally edit the README adding a description
- Push to your fork
- Wait an hour and then check mash.pkgx.sh
Note
Do not create a pull request for your scripts against this repo! We index the fork graph.
Important
Step 3 (edit the README) is not optional if you want your script to appear on the mash frontpage!
Assuming a script named foo-bar
, while debugging just:
$ chmod +x scripts/foo-bar
$ ./scripts/foo-bar
After pushing we will index your script within 60 minutes. Once indexed your script can be run with:
mash foo bar
; ormash your-username/foo-bar
Important
mash
will not be able to run your script until it is indexed.
If you can visit https://mash.pkgx.sh/USERNAME/SCRIPT-NAME then you’re
script has been indexed.
Note
- Categorized scripts occur on a first come first served basis. If you
create a script called
foo-bar
and someone already did that then you are too late and users can only call your script withmash youruser/foo-bar
. - Updates are fetched automatically, there is no versioning at this time.
- Single letter categorizations are ignored, eg
./scripts/f-u
will not be indexed or made available to mash. If you have a particularly good single letter category that you want an exception made, open a discussion and let’s chat!
Note
Think for a little about the names you are picking. We reserve the right to rename egregious abuse of names and/or namespaces. If you feel a script is misnamed open a ticket for discussion.
Thanks to pkgx
, mash
scripts can be written in any scripting language
using any packages in the entire open source ecosystem.
The shebang is where you instruct pkgx
on what scripting language you want.
For example, if you want to write your script in fish
:
#!/usr/bin/env -S pkgx fish
You can also use pkgx +pkg
syntax to add additional packages to the script’s
running environment:
#!/usr/bin/env -S pkgx +gh +git +gum +bpb bash
pkgx knows what packages to cache (it doesn’t pollute the user system with installs) based on the commands you want to run. There’s no figuring out pkg names, just type what you would type to run the command.
Rewrite the README in your fork so there is a ## mash category scriptname
section. If your script is not globally categorized then you would do
## mash username/scriptname
instead.
- The paragraph after the
##
will be the mash.pkgx.sh description- Keep it short or it’ll get truncated when we display it
- If you add a
### Usage
section we’ll list it on the web
Important
If you don’t provide a description your script won’t be listed on the
mash frontpage (but the scripts can still be run by mash
).
https://github.com/mxcl/mash
mash
has no secret sauce; users can just cURL your scripts and run them
directly via pkgx
:
$ curl -O https://raw.githubusercontent.com/mxcl/mash/main/scripts/gh-stargazer
$ pkgx ./gh-stargazer
Even pkgx
isn’t required, they can source the dependencies themselves and
run the script manually:
$ bash ./stargazer
# ^^ they will need to read the script to determine deps and interpreter
Hackers can use your script without installing pkgx
or mash
first via our
cURL one-liner. This executes the script but doesn’t install anything:
sh <(curl https://mash.pkgx.sh) <category> <scriptname>