# Build a system prompt by concatenating skill files
# Usage: load_skills core/unix-output.md domain/git.md output/plain-text.md
load_skills() {
local combined=""
for skill in "$@"; do
local path="$SKILLS_DIR/$skill"
if [[ -f "$path" ]]; then
combined+=$'\n\n'"$(cat "$path")"
else
echo "[agent-lib] WARNING: skill not found: $skill" >&2
fi
done
echo "$combined"
}
# Core invocation: reads stdin, prepends system prompt, calls claude -p
# Usage: run_agent <system_prompt> [extra claude opts...]
run_agent() {
local system_prompt="$1"
shift
local stdin_content
stdin_content=$(cat) # buffer stdin
if [[ -z "$stdin_content" ]]; then
echo "[agent] ERROR: no input on stdin" >&2
exit 1
fi
# Combine system prompt with stdin as user message
printf '%s' "$stdin_content" \
| claude -p \
--system-prompt "$system_prompt" \
--output-format text \
$CLAUDE_OPTS \
"$@"
}
# Run agent then pipe through a guard
# Usage: run_agent_guarded <guard_name> <system_prompt>
run_agent_guarded() {
local guard="$1"
shift
local system_prompt="$1"
shift
local output
output=$(run_agent "$system_prompt" "$@")
local agent_exit=$?
if [[ $agent_exit -ne 0 ]]; then
echo "$output"
exit $agent_exit
fi
# Pass through guard
echo "$output" | "$AGENTS_DIR/guards/$guard"
exit $?
}
# For structured output: run agent then validate with jq
run_json_agent() {
local system_prompt="$1"
shift
run_agent "$system_prompt" --output-format text "$@" | guard-json-valid
}
Would love to see your tiny agents project. But understand that it might contain something sensitive and will therefore stay private.