A few years back, I had a productivity conversation with Jay Miller about Alfred plugins, which led to him sharing his Bunch_Alfred plugin. At the time, I played around with the Bunch.app, a macOS automation tool, and Alfred’s support was interesting.

I created my Alfred plugin to run Just command runner commands through my Alfred setup. However, I never got around to packing or writing the plugin’s documentation.

My Alfred plugin runs Script Filter Input, which reads from a centrally located justfile and generates JSON output of all of the possible options. This will be displayed, and Alfred will run that command, whichever option you select.

Alfred plugin showing a Just command with a list of recipe options to pick from.

I was always unhappy with how the JSON document was generated from my commands, so I dusted off the project over lunch and re-engineered it by adding Pydantic support.

Alfred just announced support for a new User Interface called Text View, which could make text and markdown output from Python an exciting way to handle snippets and other productive use cases. I couldn’t quite figure it out over lunch, but now I know it’s possible, and I might figure out how to convert my Justfile Alfred plugin to generate better output.

"""
2021-2024 - Jeff Triplett
gist: https://gist.github.com/jefftriplett/e7d4eade12e30001065eed2636010772
pip install typer pydantic
Inspired/jumpstarted by: https://github.com/kjaymiller/Bunch_Alfred
"""
import os
import subprocess
import typer
from pathlib import Path
from pydantic import BaseModel
class Command(BaseModel):
arg: str
subtitle: str
title: str
class CommandContainer(BaseModel):
items: list[Command]
JUST_BIN_DEFAULT = (
"/opt/homebrew/bin/just"
if Path("/opt/homebrew/bin/just").exists()
else "/usr/local/bin/just"
)
JUST_BIN = os.environ.get("JUST_BIN", JUST_BIN_DEFAULT)
JUST_CONFIG = os.environ.get("JUST_CONFIG", Path.home() / "justfile")
def main(indent: int = None):
cmd = subprocess.run(
[
f"{JUST_BIN}",
f"--justfile={JUST_CONFIG}",
"--summary",
],
capture_output=True,
)
items = cmd.stdout.decode("utf-8").strip()
commands = items.split(" ")
if len(commands) == 0:
commands = ["--help"]
container = CommandContainer(
items=[
Command(
arg=f"{JUST_BIN} --justfile={JUST_CONFIG} {cmd}",
subtitle=f"run the {cmd} command",
title=f"{cmd}".strip(),
)
for cmd in items.split(" ")
if cmd
]
)
print(container.model_dump_json(indent=indent))
if __name__ == "__main__":
typer.run(main)