DJ Adams

Exploring Joule Studio skills

Exploring the Joule Studio skills with a quick shell script.

The new Joule Studio CLI recently landed, in the form of jl. This is what we use on the command line to initialise a new Joule Studio project. What does that mean? Well, amongst other things, it means:

Initialising a new project not only creates some harness-specific configuration1 but also retrieves this set of skills.

Skills retrieved

Here's what that looks like:

# /tmp
; jl init opencode myproj && cd myproj

Fetching system skills...
  ✓ agent (+37 resources)
  ✓ agent-evaluation (+8 resources)
  ✓ agent-extension (+9 resources)
  ✓ data-product (+11 resources)
  ✓ deploy-solution
  ✓ intent-analysis
  ✓ joule-studio-cli
  ✓ mcp-mock-config (+4 resources)
  ✓ mcp-translation-file
  ✓ n8n-workflow (+21 resources)
  ✓ product-requirements-document (+1 resource)
  ✓ setup-solution (+2 resources)
  ✓ specification (+1 resource)
✓ 13 skills initialized in myproj/.agents/skills.

Creating configuration files:
  ✓ myproj/opencode.json — created

OpenCode MCP config initialized: /tmp/myproj
# /tmp/myproj
;

The specific skills retrieved here will depend on various circumstances, you may see a slightly different list.

Browsing the skill details

I wanted to explore these skills and get a better understanding of what they were. So I wrote a quick shell script (yes, I wrote it, not AI, to help maintain my cognitive fitness2), which allows me to browse them and get an overview, like this:

Skill browser in action

A brief look at the script

The shell script, sb, now forms part of my personal development environment (PDE and also uses other tools that I have in there. Here's the script in its entirety:

#!/usr/bin/env bash

set -eo pipefail
declare FILEBROWSER=lf

fm() {

  awk '/^---$/ { if (n++) exit; next } n'

}

pv() {

  local skillfile=$1
  local width=$2

  fm < "$skillfile" \
    | yq -r '"\(.name|ascii_upcase) (\(.metadata.version))\n\n\(.description)"' \
    | fmt -s -w "$width"

}

export -f pv fm

main() {

  local loc="${1:-.}"
  local descwidth=$((($(tput cols) / 2) - 5))
  local selection

  selection="$(
    while read -r skill; do
      echo "$skill" \
        | awk -F/ '{print $4, $0}'
    done <<< "$(find "$loc" -name "SKILL.md")" \
      | fzf \
        --with-nth=1 \
        --preview "pv {2} $descwidth" \
      | cut -d' ' -f 2
  )"

  "$FILEBROWSER" "$(dirname "$selection")"

}

main "$@"

The general idea is that SKILL.md files are found, passed to fzf for selection and preview3, and then a selected skill can be drilled into as well.

Here are some notes:

That's pretty much it. The script may change a little over time, but it works for me now, and removes the friction I had which was stopping me from exploring the detail of these important assets.

Footnotes

  1. At the time of writing, this configuration consists of a section defining an MCP server and how to invoke it. More on that another time, perhaps.

  2. Also, as shell scripts (particularly Bash shell scripts, my favourite) are what agents use to get their work done in many cases, it's always good to stay on top of things to really understand what they're doing.

  3. I'm a big fan of fzf.