Files
agent-skills/skills/wordpress-cli-remote-execution/SKILL.md
T
iWP Claudy 39a637410c Initial skill library: 9 skills for delegate briefs
WordPress plugin rebrand/conventions/remote-CLI patterns, Gitea release
workflow, bastille jail provisioning, remote shell quoting safety, server
fleet map, delegate brief writing, and verification discipline -- all
derived from real incidents this session, plus two skills adapted (MIT
license, attributed) from obra/superpowers and andrej-karpathy-skills.
2026-08-02 20:08:29 +02:00

70 lines
3.2 KiB
Markdown

---
name: wordpress-cli-remote-execution
description: Use when running wp-cli commands against a WordPress site living inside a remote jail/container (via ssh + a jail-exec wrapper). Covers the output-prefix stripping gotcha and the correct user/path invocation pattern.
---
# WordPress CLI Remote Execution
## Invocation pattern
```bash
ssh user@host "bastille cmd <jail-name> sh -c 'cd /path/to/site && su -m www -c \"wp <command> --path=/path/to/site\"'"
```
Key points:
- Run wp-cli as the **web server user** (`www`, `www-data`, etc.), not
root — WordPress file ownership assumptions and some plugin behavior
depend on this.
- Always pass `--path=` explicitly rather than relying on `cd` alone
propagating through every nested layer correctly.
## GOTCHA: jail-exec wrappers prefix their own output
A wrapper like `bastille cmd <jail>` prints a `[jailname]:` header line
before the actual command output — this is the wrapper's own framing,
not part of the real output. Any script that captures this output for
further parsing must filter it out:
```bash
OUTPUT=$(ssh user@host "bastille cmd <jail> <command>" 2>&1 | grep -v "^\[<jail>\]:$")
```
Forgetting this is a common, easy-to-miss source of "the command
mysteriously failed to parse" bugs when scripting on top of jail-exec
wrappers.
## GOTCHA: `error_reporting(0)` in bootstrap files can mask real errors
Some CMS/application bootstrap files set `error_reporting(0)` globally
near the very top (often to suppress noisy legacy warnings). If you're
writing a standalone diagnostic/one-off script that `require`s such a
bootstrap file, your own errors after that point are ALSO silently
suppressed — a script can fail with **zero output and just a bad exit
code**, giving no clue why. Fix: explicitly
`error_reporting(E_ALL); ini_set('display_errors', '1');` again
**after** requiring the bootstrap, and add a
`register_shutdown_function` that dumps `error_get_last()` — this turns
a silent failure into an actual, readable error message.
## GOTCHA: glob patterns fail silently under some remote shells
`bastille cmd <jail> grep -rln 'pattern' /some/path/*.php` can fail with
`zsh: no matches found: ...` if the jail's default shell is zsh and the
glob doesn't expand as expected in that invocation context — with no
useful indication that this is a shell-globbing issue rather than "no
files matched." Fix: drop the glob and grep the directory recursively
instead (`grep -rln 'pattern' /some/path/`, no trailing `/*.ext`) — this
avoids the shell needing to expand anything at all.
## When you need to run PHP with full application bootstrap, standalone
If you need to call an application's own PHP functions/classes outside
the normal web request flow (e.g. to directly test a code path), don't
guess at which files to `require` — trace the **actual real bootstrap
sequence** the application's own front controller uses (e.g. its
`index.php`) by reading it, and replicate that exact require order in
your standalone script. Skipping steps because "this part probably isn't
needed" reliably produces a cascade of "undefined function/class" errors
that have to be debugged one require statement at a time — reading the
real bootstrap sequence once up front is faster than that cascade.