Skip to content

Commit 2531295

Browse files
committed
feat: Add WP Plugin Development and Project Triage Skills
- Created `test/skills/wp-plugin-development/SKILL.md` to define the skill for developing WordPress plugins, detailing architecture, hooks, activation/deactivation, admin UI, security, and release packaging. - Added references for various aspects of plugin development: - `references/data-and-cron.md`: Guidelines for data storage, cron tasks, and upgrade routines. - `references/debugging.md`: Quick debugging routes for common issues like plugin loading failures and settings not saving. - `references/lifecycle.md`: Instructions for managing activation, deactivation, and uninstall hooks. - `references/security.md`: Security best practices for plugins, including nonces, sanitization, and escaping. - `references/settings-api.md`: Guidelines for using the Settings API for admin options. - `references/structure.md`: Best practices for plugin structure and loading. - Introduced `test/skills/wp-plugin-development/scripts/detect_plugins.mjs` to detect WordPress plugins in a repository by scanning PHP files for plugin headers. - Created `test/skills/wp-project-triage/SKILL.md` to define the skill for inspecting WordPress repositories, including tooling, tests, and version hints. - Added `test/skills/wp-project-triage/references/triage.schema.json` to provide a JSON schema for the project triage report. - Implemented `test/skills/wp-project-triage/scripts/detect_wp_project.mjs` to analyze the repository structure, detect project types, and generate a structured report with recommendations based on the findings.
1 parent 99b15de commit 2531295

File tree

16 files changed

+1407
-9
lines changed

16 files changed

+1407
-9
lines changed

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,23 @@
22

33
All notable changes to this project will be documented in this file.
44

5+
## [1.1.0] - 2026-01-12
6+
7+
### Added
8+
- `--skill <a[,b,...]>` support in `ralph.sh` and `ralph-once.sh` (prepends `skills/<name>/SKILL.md` into the attached context).
9+
- `--only <prompt1[,prompt2...]>` filter in `test/run-prompts.sh` to run selected prompt tests.
10+
- Vendored WordPress skills under `test/skills/` for the harness:
11+
12+
- `wp-plugin-development`
13+
- `wp-project-triage`
14+
15+
### Fixed
16+
- `test/run-prompts.sh`: WordPress skill staging now copies from `$ROOT/test/skills/...` (so it works inside per-prompt worktrees).
17+
- `test/run-prompts.sh`: WordPress assertions/skill injection now match `wordpress-plugin-agent.txt` consistently.
18+
19+
### Changed
20+
- `test/run-prompts.sh`: WordPress prompt test now stages those vendored skills into a top-level `skills/` folder inside the worktree and injects the WP plugin skill into the context attachment.
21+
522
## [1.0.0] - 2026-01-10
623

724
### Added

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ MODEL=claude-opus-4.5 ./ralph-once.sh --prompt prompts/default.txt --prd plans/p
140140
|--------------------------|--------------------------------------|-----------------------|
141141
| `--prompt <file>` | Load prompt from file (required) ||
142142
| `--prd <file>` | Optionally attach a PRD JSON file ||
143+
| `--skill <a[,b,...]>` | Prepend skills from `skills/<name>/SKILL.md` ||
143144
| `--allow-profile <name>` | Permission profile (see below) ||
144145
| `--allow-tools <spec>` | Allow specific tool (repeatable) ||
145146
| `--deny-tools <spec>` | Deny specific tool (repeatable) ||
@@ -271,6 +272,24 @@ Ralph always denies a small set of dangerous commands (currently `shell(rm)` and
271272
- Single attachment workaround: Ralph combines PRD + `progress.txt` into one context file to avoid Copilot CLI issues with multiple `@file` attachments.
272273
- Pseudo-TTY capture in the harness: `test/run-prompts.sh` uses `script(1)` to capture output even when Copilot writes directly to the TTY.
273274

275+
### Skills (`--skill`)
276+
277+
Skills let you prepend reusable instructions into the same attached context file.
278+
Pass a comma-separated list (repeatable):
279+
280+
- `--skill wp-block-development` loads `skills/wp-block-development/SKILL.md`
281+
- `--skill aa,bb,cc` loads `skills/aa/SKILL.md`, `skills/bb/SKILL.md`, `skills/cc/SKILL.md`
282+
283+
Example:
284+
285+
```bash
286+
./ralph.sh --prompt prompts/wordpress-plugin-agent.txt \
287+
--skill wp-block-development,wp-cli \
288+
--prd plans/prd.json \
289+
--allow-profile safe \
290+
5
291+
```
292+
274293
---
275294

276295

ralph-once.sh

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
#!/usr/bin/env bash
22
set -euo pipefail
33

4-
RALPH_VERSION="1.0.0"
4+
RALPH_VERSION="1.1.0"
55

66
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
77

88
usage() {
99
cat <<USAGE
1010
Usage:
11-
$0 --prompt <file> [--prd <file>] [--allow-profile <safe|dev|locked>] [--allow-tools <toolSpec> ...] [--deny-tools <toolSpec> ...]
11+
$0 --prompt <file> [--prd <file>] [--skill <a[,b,...]>] [--allow-profile <safe|dev|locked>] [--allow-tools <toolSpec> ...] [--deny-tools <toolSpec> ...]
1212
1313
Options:
1414
--prompt <file> Load prompt text from file (required).
1515
--prd <file> Optionally attach a PRD JSON file.
16+
--skill <a[,b,...]> Prepend one or more skills from skills/<name>/SKILL.md (comma-separated).
1617
--allow-profile <name> Tool permission profile: safe | dev | locked.
1718
--allow-tools <toolSpec> Allow a specific tool (repeatable). Example: --allow-tools write
1819
Use quotes if the spec includes spaces: --allow-tools 'shell(git push)'
@@ -26,12 +27,20 @@ USAGE
2627

2728
prompt_file=""
2829
prd_file=""
30+
skills_csv=""
2931
allow_profile=""
3032
declare -a allow_tools
3133
declare -a deny_tools
3234
allow_tools=()
3335
deny_tools=()
3436

37+
trim() {
38+
local s="$1"
39+
s="${s#"${s%%[![:space:]]*}"}"
40+
s="${s%"${s##*[![:space:]]}"}"
41+
printf '%s' "$s"
42+
}
43+
3544
while [[ $# -gt 0 ]]; do
3645
case "$1" in
3746
--prompt)
@@ -63,6 +72,34 @@ while [[ $# -gt 0 ]]; do
6372
fi
6473
shift
6574
;;
75+
--skill)
76+
shift
77+
if [[ $# -lt 1 || -z "${1:-}" ]]; then
78+
echo "Error: --skill requires a value" >&2
79+
usage
80+
exit 1
81+
fi
82+
if [[ -n "$skills_csv" ]]; then
83+
skills_csv+=",$1"
84+
else
85+
skills_csv="$1"
86+
fi
87+
shift
88+
;;
89+
--skill=*)
90+
v="${1#--skill=}"
91+
if [[ -z "$v" ]]; then
92+
echo "Error: --skill requires a value" >&2
93+
usage
94+
exit 1
95+
fi
96+
if [[ -n "$skills_csv" ]]; then
97+
skills_csv+=",$v"
98+
else
99+
skills_csv="$v"
100+
fi
101+
shift
102+
;;
66103
--allow-profile)
67104
shift
68105
if [[ $# -lt 1 || -z "${1:-}" ]]; then
@@ -139,6 +176,12 @@ if [[ ! -r "$progress_file" ]]; then
139176
exit 1
140177
fi
141178

179+
declare -a skills
180+
skills=()
181+
if [[ -n "$skills_csv" ]]; then
182+
IFS=',' read -r -a skills <<<"$skills_csv"
183+
fi
184+
142185
if [[ -z "$allow_profile" ]] && [[ ${#allow_tools[@]} -eq 0 ]]; then
143186
echo "Error: you must specify --allow-profile or at least one --allow-tools" >&2
144187
usage
@@ -196,6 +239,25 @@ context_file="$(mktemp .ralph-context.XXXXXX)"
196239
{
197240
echo "# Context"
198241
echo
242+
if [[ ${#skills[@]} -gt 0 ]]; then
243+
echo "## Skills"
244+
for raw in "${skills[@]}"; do
245+
skill="$(trim "$raw")"
246+
if [[ -z "$skill" ]]; then
247+
continue
248+
fi
249+
skill_file="skills/$skill/SKILL.md"
250+
if [[ ! -r "$skill_file" ]]; then
251+
echo "Error: skill not found/readable: $skill_file" >&2
252+
exit 1
253+
fi
254+
echo
255+
echo "### $skill"
256+
echo
257+
cat "$skill_file"
258+
done
259+
echo
260+
fi
199261
if [[ -n "$prd_file" ]]; then
200262
echo "## PRD ($prd_file)"
201263
cat "$prd_file"

ralph.sh

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
#!/usr/bin/env bash
22
set -euo pipefail
33

4-
RALPH_VERSION="1.0.0"
4+
RALPH_VERSION="1.1.0"
55

66
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
77

88
usage() {
99
cat <<USAGE
1010
Usage:
11-
$0 --prompt <file> [--prd <file>] [--allow-profile <safe|dev|locked>] [--allow-tools <toolSpec> ...] [--deny-tools <toolSpec> ...] <iterations>
11+
$0 --prompt <file> [--prd <file>] [--skill <a[,b,...]>] [--allow-profile <safe|dev|locked>] [--allow-tools <toolSpec> ...] [--deny-tools <toolSpec> ...] <iterations>
1212
1313
Options:
1414
--prompt <file> Load prompt text from file (required).
1515
--prd <file> Optionally attach a PRD JSON file.
16+
--skill <a[,b,...]> Prepend one or more skills from skills/<name>/SKILL.md (comma-separated).
1617
--allow-profile <name> Tool permission profile: safe | dev | locked.
1718
--allow-tools <toolSpec> Allow a specific tool (repeatable). Example: --allow-tools write
1819
Use quotes if the spec includes spaces: --allow-tools 'shell(git push)'
@@ -26,12 +27,20 @@ USAGE
2627

2728
prompt_file=""
2829
prd_file=""
30+
skills_csv=""
2931
allow_profile=""
3032
declare -a allow_tools
3133
declare -a deny_tools
3234
allow_tools=()
3335
deny_tools=()
3436

37+
trim() {
38+
local s="$1"
39+
s="${s#"${s%%[![:space:]]*}"}"
40+
s="${s%"${s##*[![:space:]]}"}"
41+
printf '%s' "$s"
42+
}
43+
3544
while [[ $# -gt 0 ]]; do
3645
case "$1" in
3746
--prompt)
@@ -63,6 +72,34 @@ while [[ $# -gt 0 ]]; do
6372
fi
6473
shift
6574
;;
75+
--skill)
76+
shift
77+
if [[ $# -lt 1 || -z "${1:-}" ]]; then
78+
echo "Error: --skill requires a value" >&2
79+
usage
80+
exit 1
81+
fi
82+
if [[ -n "$skills_csv" ]]; then
83+
skills_csv+=",$1"
84+
else
85+
skills_csv="$1"
86+
fi
87+
shift
88+
;;
89+
--skill=*)
90+
v="${1#--skill=}"
91+
if [[ -z "$v" ]]; then
92+
echo "Error: --skill requires a value" >&2
93+
usage
94+
exit 1
95+
fi
96+
if [[ -n "$skills_csv" ]]; then
97+
skills_csv+=",$v"
98+
else
99+
skills_csv="$v"
100+
fi
101+
shift
102+
;;
66103
--allow-profile)
67104
shift
68105
if [[ $# -lt 1 || -z "${1:-}" ]]; then
@@ -151,6 +188,12 @@ if [[ ! -r "$progress_file" ]]; then
151188
exit 1
152189
fi
153190

191+
declare -a skills
192+
skills=()
193+
if [[ -n "$skills_csv" ]]; then
194+
IFS=',' read -r -a skills <<<"$skills_csv"
195+
fi
196+
154197
if [[ -z "$allow_profile" ]] && [[ ${#allow_tools[@]} -eq 0 ]]; then
155198
echo "Error: you must specify --allow-profile or at least one --allow-tools" >&2
156199
usage
@@ -209,6 +252,25 @@ for ((i=1; i<=iterations; i++)); do
209252
{
210253
echo "# Context"
211254
echo
255+
if [[ ${#skills[@]} -gt 0 ]]; then
256+
echo "## Skills"
257+
for raw in "${skills[@]}"; do
258+
skill="$(trim "$raw")"
259+
if [[ -z "$skill" ]]; then
260+
continue
261+
fi
262+
skill_file="skills/$skill/SKILL.md"
263+
if [[ ! -r "$skill_file" ]]; then
264+
echo "Error: skill not found/readable: $skill_file" >&2
265+
exit 1
266+
fi
267+
echo
268+
echo "### $skill"
269+
echo
270+
cat "$skill_file"
271+
done
272+
echo
273+
fi
212274
if [[ -n "$prd_file" ]]; then
213275
echo "## PRD ($prd_file)"
214276
cat "$prd_file"

0 commit comments

Comments
 (0)