stepped-demo-script — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited stepped-demo-script (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Compose a single bash file that a human can paste into their terminal and walk through, one step at a time, and see at each step (a) what the script is doing, (b) the command's output, and (c) whether the outcome matched expectations. The reader is often not the author – could be a teammate, a stakeholder, a support engineer on the other side of a ticket – so the script needs to be self-contained, legible without context, and not terrifying to open.
The goal is authoring velocity: the user starts most of these from a blank page, and the skill's job is to get them past the blank page with the right bones in place, not to dictate the body.
Trigger when the user wants a runnable script that demonstrates a process by calling out each step and pausing for the reader. Common shapes:
Skip when the script shouldn't pause (CI, cron, piped-to-file), when there's no stepping (a single long command), or when the "demo" is really a tutorial document (that's Markdown, not bash).
expect can surface the mismatch). Don't over-interview – a one-line scenario plus a list of steps is enough to draft.examples/ to seed the structure (API sequence or CLI walkthrough). Read the full example before drafting – the shape matters more than any one line.references/primitives.md: announce, section, expect, pause, plus the _jq/$c/$x constants. Each step is roughly announce "what I'm about to do" → <command> → pause, with an expect line afterward if there's an outcome to assert.examples/api-sequence.sh). Functions wrap the command + its announce, not the pause – pauses stay at the call site so step granularity is controlled by the caller.announce line, fix the announce, not the code../demo.sh, squash-demo.sh) pollutes whatever directory the user invoked the skill from -- they may be inside a repo, and the demo doesn't belong there. Default to /tmp/<scenario-slug>.sh; pick a different absolute path only if the user names one. The user-facing chat answer should be ~1-2 sentences pointing at the file (e.g. "Script is at /tmp/find-delete-demo.sh -- run it with bash /tmp/find-delete-demo.sh. Each step pauses for Enter.").Every script starts with the same block. It's ~15 lines – don't trim it, don't "modernize" it, don't swap it for sourcing a helper. A self-contained script means the reader never has to chase a dependency.
#!/bin/bash
# --- Demo prelude ----------------------------------------------------
command -v jq >/dev/null 2>&1 && _jq() { jq ${NO_COLOR:+-M} "$@"; } || _jq() { cat; }
c=$'\342\234\205' # ✅ check
x=$'\342\235\214' # ❌ cross
if [[ -z "$NO_COLOR" && -t 1 ]]; then
DIM=$'\033[2m'; BOLD=$'\033[1m'; RESET=$'\033[0m'
else
DIM=''; BOLD=''; RESET=''
fi
announce() { printf '%s- %s%s\n' "$BOLD" "$*" "$RESET"; }
section() { printf '\n%s== %s ==%s\n' "$BOLD" "$*" "$RESET"; }
expect() {
local e="$1" a="${2-$1}"
if [[ "$e" == "$a" ]]; then
printf '%s> expected: %s %s%s\n' "$DIM" "$e" "$c" "$RESET"
else
printf '%s> expected: %s %s actual: %s%s\n' "$DIM" "$e" "$x" "$a" "$RESET"
fi
}
pause() {
[[ -n "$DEMO_NO_PAUSE" || ! -t 0 ]] && return
read -rp "<Enter to continue...>" && printf '\033[A\033[2K\n'
}
# ---------------------------------------------------------------------Why each piece is there – you'll want to understand these so you can answer questions and handle edge cases:
cat when jq isn't installed. JSON responses stay readable either way – no setup instructions needed before running.expect uses them automatically; expose them directly for hand-rolled lines (mixed-result summaries, rare cases).NO_COLOR, -t 1) mean the script outputs clean text when piped to a file or when the reader opts out. Respecting NO_COLOR is a widely-followed convention and costs one line of setup.expected: X ✅); two args means "expected vs. actual differ" (expected: X ❌ actual: Y). Don't codify a third "I don't know what's correct" mode – if the author isn't confident enough to state what's expected, the demo isn't ready.DEMO_NO_PAUSE=1 for non-interactive runs and auto-skips when stdin isn't a terminal (piping into bash, CI). The \033[A\033[2K\n sequence moves the cursor up one line and clears it, so the <Enter to continue...> prompt doesn't leave a trail in the scrollback.Each step is almost always one of three shapes:
Simple step (most common):
announce "Create a basket for cookieId $cookieId"
curl -s -X POST ... | _jq
pauseStep with an assertion (demo asserts the outcome):
announce "Fetch recommendations"
get_recs
expect "3 results including pinned item"
pauseStep demonstrating misbehavior (the whole point of the repro):
announce "Request with the malformed header"
curl -s ... | _jq
expect "400 bad_request" "500 internal_error"
pauseA reusable call lifts into a shell function that includes its own announce:
get_recs() {
announce "GET /recommendations for cookieId $cookieId"
curl -s ... | _jq
}
get_recs
expect "3 results"
pauseNote the pause stays outside the function. This is intentional: the caller owns when the reader gets to read the output, because the same function might be called in a phase where a pause is wanted and another where it isn't.
info helper for one-off context lines, a warn helper for caveats, a summary helper for the last line – each of these is a bare echo or printf and shouldn't earn a slot. Bloating the prelude makes the reader trace more code before they can read the demo.announce and expect color themselves because they're narrator lines competing with command output. The command output itself (curl | _jq, CLI tool output) stays in its default colors – don't wrap it in $DIM or similar.bash v4 features, or on BusyBox, or under set -u, call that out to the user – the prelude assumes plain bash on a reasonable-enough system (macOS/Linux defaults) and adding portability shims inflates it fast.main() adds a call site the reader has to find.set -e would mask that. Let each step run and let the reader judge. If a step genuinely must succeed before the next makes sense, the user can inline a check (|| { echo "..."; exit 1; }) and the skill shouldn't pre-emptively wire it in.templates/minimal.sh – copy-paste starting point. Prelude + one step + done. Use this when there's no closer example.examples/api-sequence.sh – unauthenticated GitHub API walkthrough. Demonstrates: announce/expect/pause in a cURL flow, lifting a repeated call into a function, using section to split phases, misbehavior mode via two-arg expect.examples/cli-walkthrough.sh – git walkthrough (init → commit → branch → merge-conflict → resolve) in a temp dir. Demonstrates the same primitives applied to non-HTTP commands, and the "demo creates and cleans up its own sandbox" pattern.references/primitives.md – detailed rationale for each primitive, when to reach for which, and patterns (reusable-call functions, multi-phase scripts, env-variable escape hatches).~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.