Created
September 16, 2025 06:08
-
-
Save fumikito/c1a4ea6f5285aeb56bea2176820a0b41 to your computer and use it in GitHub Desktop.
Local by FlyWheelのWordPressサイト(Docker)に生成AIが直接アクセスできるようにするCLIのショートハンドスクリプト
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# local-wp — Run commands inside a Local by Flywheel site shell non-interactively. | |
# | |
# About: | |
# このシェルスクリプトはClaude Codeなどの生成AIツールがLocalのDocker内でCLIコマンドを実行するためのヘルパースクリプトです。 | |
# CLAUDE.mdなどに書いておくと、Vibe Codingが捗ります。 | |
# ChatGPT 5と一緒に作りました。 | |
# | |
# Installation: | |
# 1. パスの通った場所にインストールしてください。たとえば、 `~/bin/local-wp` として保存します。 | |
# 2. 実行権限を付与します。 `chmod +x ~/bin/local-wp` | |
# | |
# Usage: | |
# local-wp <site_name> -- <command ...> | |
# local-wp --list | |
# local-wp --help | |
# | |
set -Eeuo pipefail | |
SSH_DIR="$HOME/Library/Application Support/Local/ssh-entry" | |
usage() { | |
cat <<'EOF' | |
Usage: | |
local-wp <site_name> -- <command ...> | |
local-wp --list | |
local-wp --help | |
Notes: | |
- 各サイトで一度は GUI の「Open Site Shell」を実行しておくと ssh-entry が作成されます。 | |
- サイトは Local.app で起動中である必要があります。 | |
- <site_name> は「Local Sites/<site_name>」のフォルダ名です(空白可)。 | |
EOF | |
} | |
die() { echo "✗ $*" >&2; exit 1; } | |
# どんな保存場所でもOK: ssh-entryの中から "/.../app/public" を拾ってサイト名を推定 | |
extract_site_name() { | |
local f="$1" raw path site_root site_name | |
# 末尾が /app/public の絶対パス(両側の'や"はあってもなくてもOK)を1つ抜く | |
raw="$(grep -m1 -Eo '["'"'"']?/[A-Za-z0-9._~/: -]*/app/public["'"'"']?' "$f" || true)" || true | |
[[ -n "$raw" ]] || return 1 | |
raw="${raw%\"}"; raw="${raw%\'}"; raw="${raw#\"}"; raw="${raw#\'}" | |
path="$raw" | |
site_root="${path%/app/public}" | |
site_name="${site_root##*/}" # 例: /…/minicome → minicome | |
printf '%s\n' "$site_name" | |
} | |
list_sites() { | |
local f name | |
shopt -s nullglob | |
for f in "$SSH_DIR"/*.sh; do | |
name="$(extract_site_name "$f" || true)" | |
[[ -n "$name" ]] && printf '%s\n' "$name" | |
done | sort -u | |
} | |
find_script_for_site() { | |
local target="$1" lc_target lc_name f name best="" | |
lc_target="$(printf '%s' "$target" | tr '[:upper:]' '[:lower:]')" | |
shopt -s nullglob | |
# ★ 空白を壊さない:lsやコマンド置換は使わず、そのままループ | |
for f in "$SSH_DIR"/*.sh; do | |
name="$(extract_site_name "$f" || true)" || continue | |
lc_name="$(printf '%s' "$name" | tr '[:upper:]' '[:lower:]')" | |
if [[ "$lc_name" == "$lc_target" ]]; then | |
printf '%s\n' "$f" | |
return 0 | |
fi | |
[[ -z "$best" && "$lc_name" == *"$lc_target"* ]] && best="$f" | |
done | |
[[ -n "$best" ]] && { printf '%s\n' "$best"; return 0; } | |
return 1 | |
} | |
main() { | |
[[ "${1:-}" == "--help" ]] && { usage; exit 0; } | |
[[ "${1:-}" == "--list" ]] && { list_sites; exit 0; } | |
[[ -d "$SSH_DIR" ]] || die "ssh-entry が見つかりません: $SSH_DIR" | |
[[ $# -ge 1 ]] || { usage; exit 1; } | |
local site="$1"; shift || true | |
[[ "${1:-}" == "--" ]] && shift || true | |
[[ $# -ge 1 ]] || die "実行コマンドがありません。例: local-wp \"$site\" -- wp plugin list" | |
# サイト名に空白があっても OK(grep マッチは文字列完全一致) | |
script="$(find_script_for_site "$site" || true)" | |
[[ -n "${script:-}" ]] || die "対象サイトの ssh-entry が見つかりません: $site | |
ヒント: 1) Local でサイトを起動 2) 一度「Open Site Shell」を実行 3) site 名の綴りを確認" | |
# 引数を安全にクォートして 1 行に整形(bash 3.2 互換) | |
local Q=""; printf -v Q '%q ' "$@"; Q="${Q% }" | |
# 1) ssh-entryから対話起動系を除去した一時ファイルを作る | |
tmp="$(mktemp -t localwp.XXXXXX)" | |
# exec $SHELL と 「Launching shell: …」の行を削除 | |
sed -E '/^exec[[:space:]]+\$SHELL[[:space:]]*$/d;/Launching shell:/d' "$script" > "$tmp" | |
# 2) “ほぼ空”の環境でサブシェル起動し、無害化したssh-entryをsource → コマンド実行 | |
/usr/bin/env -i HOME="$HOME" USER="$USER" LOGNAME="${LOGNAME:-$USER}" \ | |
PATH="/usr/bin:/bin:/usr/local/bin" TERM="${TERM:-xterm-256color}" SHELL="/bin/bash" \ | |
/bin/bash -lc "unset PROMPT_COMMAND BASH_ENV ENV; source \"$tmp\" >/dev/null 2>&1; ${Q}" | |
status=$? | |
# 3) 後始末 | |
rm -f "$tmp" | |
exit "$status" | |
} | |
main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment