diff --git a/README.md b/README.md index 20b1d7d..82f5131 100644 --- a/README.md +++ b/README.md @@ -129,7 +129,7 @@ systemctl start kimaki # or: systemctl start cc-connect | `--chat ` | Chat bridge: `kimaki` (Discord, default for OpenCode), `cc-connect` (default for Claude Code and Studio Code), `telegram` | | `--multisite` | Convert to WordPress Multisite (subdirectory by default) | | `--subdomain` | Subdomain multisite (use with `--multisite`, requires wildcard DNS) | -| `--no-skills` | Skip WordPress agent skills | +| `--no-skills` | Skip wp-coding-agents skills | | `--skip-deps` | Skip apt packages | | `--skip-ssl` | Skip SSL/HTTPS | | `--root` | Run agent as root (default on VPS) | @@ -184,7 +184,7 @@ SITE_DOMAIN=example.com ./setup.sh --dry-run | **[Homeboy](https://github.com/Extra-Chill/homeboy)** | Optional developer power layer for project status, component-aware checks, review loops, and WordPress extension verification | `--with-homeboy` | | **[Kimaki](https://kimaki.xyz)**, **[cc-connect](https://github.com/nichochar/cc-connect)**, or **[opencode-telegram](https://github.com/grinev/opencode-telegram-bot)** | Chat bridge (Discord, multi-platform, or Telegram) | `--no-chat` | | **SessionStart hook** | Syncs Data Machine agents into CLAUDE.md on every session (Claude Code and Studio Code) | Always installed | -| **[WordPress agent skills](https://github.com/WordPress/agent-skills)** | WP development patterns (cloned at install) | `--no-skills` | +| **wp-coding-agents skills** | Setup and upgrade runbooks shipped with this repo. The composed `AGENTS.md` provides the site-specific WordPress, Data Machine, and Homeboy operating context, so setup does not install redundant external skills. | `--no-skills` | ## VPS vs. Local diff --git a/bridges/kimaki/post-upgrade.sh b/bridges/kimaki/post-upgrade.sh index ce99f05..071ffb9 100755 --- a/bridges/kimaki/post-upgrade.sh +++ b/bridges/kimaki/post-upgrade.sh @@ -63,6 +63,18 @@ fi KILL_LIST="$(dirname "$0")/skills-kill-list.txt" REQUIRED_PLUGINS=(dm-context-filter.ts dm-agent-sync.ts) +WP_CODING_AGENTS_SKILLS=(upgrade-wp-coding-agents wp-coding-agents-setup) + +is_wp_coding_agents_skill() { + local candidate="$1" + local skill + + for skill in "${WP_CODING_AGENTS_SKILLS[@]}"; do + [[ "$candidate" == "$skill" ]] && return 0 + done + + return 1 +} is_killed_skill() { local candidate="$1" @@ -127,6 +139,10 @@ elif [[ -d "$SKILL_SOURCE_DIR" ]]; then echo "kimaki-config: skipped killed skill $skill_name" continue fi + if ! is_wp_coding_agents_skill "$skill_name"; then + echo "kimaki-config: skipped unmanaged skill $skill_name" + continue + fi if [[ -f "$skill_dir/SKILL.md" ]]; then target="$SKILLS_DIR/$skill_name" rm -rf "$target" diff --git a/lib/skills.sh b/lib/skills.sh index 6a79a81..93c8994 100644 --- a/lib/skills.sh +++ b/lib/skills.sh @@ -1,35 +1,40 @@ #!/bin/bash -# Skills: agent skill installation from git repos and the wp-coding-agents repo itself +# Skills: agent skill installation from the wp-coding-agents repo itself. +# Site-specific WordPress, Data Machine, and Homeboy guidance belongs in the +# composed AGENTS.md, which is fresher than static external skill snapshots. -# Install agent skills from a git repo. -# Clones the repo, copies directories containing SKILL.md to the target. -install_skills_from_repo() { - local repo_url="$1" - local label="${2:-skills}" +WP_CODING_AGENTS_SKILLS=(upgrade-wp-coding-agents wp-coding-agents-setup) - if [ "$DRY_RUN" = true ]; then - echo -e "${BLUE}[dry-run]${NC} git clone --depth 1 $repo_url (extract skill dirs to $SKILLS_DIR)" - return - fi +is_wp_coding_agents_skill() { + local candidate="$1" + local skill - local tmp_dir - tmp_dir=$(mktemp -d) - rmdir "$tmp_dir" 2>/dev/null || true # git_clone_with_retry needs a non-existent target on retry. - if git_clone_with_retry "$repo_url" "$tmp_dir" --depth 1; then - for skill_dir in "$tmp_dir"/*/; do - local skill_name - skill_name=$(basename "$skill_dir") - if [ -f "$skill_dir/SKILL.md" ]; then - rm -rf "$SKILLS_DIR/$skill_name" - cp -r "$skill_dir" "$SKILLS_DIR/$skill_name" - log " Installed skill: $skill_name" - fi - done - rm -rf "$tmp_dir" - log "$label installed (latest version)" - else - warn "Could not clone $label from $repo_url" - rm -rf "$tmp_dir" + for skill in "${WP_CODING_AGENTS_SKILLS[@]}"; do + [ "$candidate" = "$skill" ] && return 0 + done + + return 1 +} + +remove_unmanaged_skills() { + local target_dir="$1" + local label="$2" + + [ -d "$target_dir" ] || return + + local removed=0 + local skill_dir skill_name + for skill_dir in "$target_dir"/*/; do + [ -d "$skill_dir" ] || continue + skill_name=$(basename "$skill_dir") + if [ -f "$skill_dir/SKILL.md" ] && ! is_wp_coding_agents_skill "$skill_name"; then + rm -rf "$skill_dir" + removed=$((removed + 1)) + fi + done + + if [ "$removed" -gt 0 ]; then + log "Removed unmanaged skills from $label: $target_dir/ ($removed)" fi } @@ -42,18 +47,24 @@ install_skills_from_local_repo() { [ -d "$src_dir" ] || return if [ "$DRY_RUN" = true ]; then + echo -e "${BLUE}[dry-run]${NC} Would remove unmanaged skills from $SKILLS_DIR/" for skill_dir in "$src_dir"/*/; do + local skill_name + skill_name=$(basename "$skill_dir") [ -f "$skill_dir/SKILL.md" ] || continue - echo -e "${BLUE}[dry-run]${NC} Would install in-repo skill: $(basename "$skill_dir") → $SKILLS_DIR/" + is_wp_coding_agents_skill "$skill_name" || continue + echo -e "${BLUE}[dry-run]${NC} Would install in-repo skill: $skill_name → $SKILLS_DIR/" done return fi + remove_unmanaged_skills "$SKILLS_DIR" "runtime skills dir" + local copied=0 for skill_dir in "$src_dir"/*/; do local skill_name skill_name=$(basename "$skill_dir") - if [ -f "$skill_dir/SKILL.md" ]; then + if [ -f "$skill_dir/SKILL.md" ] && is_wp_coding_agents_skill "$skill_name"; then rm -rf "$SKILLS_DIR/$skill_name" cp -r "$skill_dir" "$SKILLS_DIR/$skill_name" log " Installed skill: $skill_name" @@ -65,8 +76,8 @@ install_skills_from_local_repo() { fi } -# Mirror every SKILL.md-containing subdir from $SKILLS_DIR into the -# persistent kimaki-config/skills/ dir. This is the durable source of +# Mirror wp-coding-agents-owned skills into the persistent +# kimaki-config/skills/ dir. This is the durable source of # truth that survives `npm update -g kimaki` wipes — kimaki/post-upgrade.sh # reads from this path on every kimaki restart to restore the mirror copy # at $(npm root -g)/kimaki/skills/. @@ -93,12 +104,14 @@ install_skills_to_persistent_source() { return } + remove_unmanaged_skills "$persistent_dir" "persistent source" + local copied=0 - for skill_dir in "$SKILLS_DIR"/*/; do + for skill_dir in "$SCRIPT_DIR/skills"/*/; do [ -d "$skill_dir" ] || continue local skill_name skill_name=$(basename "$skill_dir") - if [ -f "$skill_dir/SKILL.md" ]; then + if [ -f "$skill_dir/SKILL.md" ] && is_wp_coding_agents_skill "$skill_name"; then rm -rf "$persistent_dir/$skill_name" cp -r "$skill_dir" "$persistent_dir/$skill_name" copied=$((copied + 1)) @@ -176,8 +189,6 @@ install_skills() { run_cmd mkdir -p "$SKILLS_DIR" install_skills_from_local_repo - install_skills_from_repo "https://github.com/WordPress/agent-skills.git" "WordPress agent skills" - install_skills_from_repo "https://github.com/Extra-Chill/data-machine-skills.git" "Data Machine skills" done # Reset SKILLS_DIR back to the primary for downstream consumers @@ -194,9 +205,9 @@ install_skills() { elif command -v kimaki &> /dev/null; then KIMAKI_SKILLS_DIR="$(npm root -g 2>/dev/null)/kimaki/skills" if [ -d "$KIMAKI_SKILLS_DIR" ]; then - for skill_dir in "$SKILLS_DIR"/*/; do + for skill_dir in "$SCRIPT_DIR/skills"/*/; do skill_name=$(basename "$skill_dir") - if [ -f "$skill_dir/SKILL.md" ]; then + if [ -f "$skill_dir/SKILL.md" ] && is_wp_coding_agents_skill "$skill_name"; then cp -r "$skill_dir" "$KIMAKI_SKILLS_DIR/$skill_name" fi done diff --git a/setup.sh b/setup.sh index 3b9b768..4bcfca7 100755 --- a/setup.sh +++ b/setup.sh @@ -12,7 +12,8 @@ # Without Discord: ./setup.sh --no-chat # # Data Machine is the substrate wp-coding-agents composes on top of — memory -# files (SOUL/MEMORY/USER/RULES/SITE), auto-composed AGENTS.md, skills, +# files (SOUL/MEMORY/USER/RULES/SITE), auto-composed AGENTS.md, +# wp-coding-agents skills, # workspace primitive, MCP surface. It is not optional. Uninstall the plugin # later if you don't want it. # @@ -200,13 +201,13 @@ OPTIONS: --skip-deps Skip apt package installation --multisite Convert to WordPress Multisite (subdirectory by default) --subdomain Use subdomain multisite (requires wildcard DNS; use with --multisite) - --no-skills Skip WordPress agent skills installation + --no-skills Skip wp-coding-agents skill installation --with-homeboy Create/update a Homeboy project and install/verify the WordPress Homeboy extension --no-homeboy Skip Homeboy project setup, even if homeboy is installed --homeboy-project-id Override Homeboy project ID (default: agent/site slug) - --skills-only Only run skills installation on existing site + --skills-only Only run wp-coding-agents skill installation on existing site --skip-ssl Skip SSL/HTTPS configuration --root Run agent as root (default) --non-root Run agent as dedicated service user (opencode) diff --git a/skills/wp-coding-agents-setup/SKILL.md b/skills/wp-coding-agents-setup/SKILL.md index 7b90059..f838ea2 100644 --- a/skills/wp-coding-agents-setup/SKILL.md +++ b/skills/wp-coding-agents-setup/SKILL.md @@ -113,7 +113,7 @@ Based on their answers, construct the appropriate command: Add `--skip-deps` if nginx, PHP, MySQL, Node are already installed. Add `--skip-ssl` to skip Let's Encrypt certificate. Add `--root` to run the agent as root (default is dedicated service user). -Add `--no-skills` to skip WordPress agent skills. +Add `--no-skills` to skip wp-coding-agents skills. Add `--agent-slug ` to override the Data Machine agent slug. Add `--with-homeboy` when the user wants the optional Homeboy developer power layer. Homeboy remains external; setup should verify or install the CLI and WordPress extension, create/update a Homeboy project for the WordPress site root, attach eligible Data Machine Code primary workspace checkouts as components, skip `@` worktrees by default, sync `datamachine_code_homeboy_available`, and recompose `AGENTS.md`. diff --git a/tests/post-upgrade-restore.sh b/tests/post-upgrade-restore.sh index 87b5e0f..8e1ec6f 100755 --- a/tests/post-upgrade-restore.sh +++ b/tests/post-upgrade-restore.sh @@ -7,8 +7,8 @@ # # What we cover: # 1. Kill pass removes a blacklisted skill from the simulated skills dir. -# 2. Skill restore pass copies a SKILL.md tree from the persistent source -# back into the (wiped) skills dir. +# 2. Skill restore pass copies wp-coding-agents SKILL.md trees from the +# persistent source back into the (wiped) skills dir. # 3. Default plugin pass is a no-op because opencode loads the persistent # source dir directly. # 4. Explicit KIMAKI_PLUGINS_DIR compatibility override still copies *.ts @@ -55,16 +55,25 @@ echo "stub" > "$LIVE_SKILLS/blacklisted-skill/SKILL.md" mkdir -p "$LIVE_SKILLS/persisted-blacklisted-skill" echo "stub" > "$LIVE_SKILLS/persisted-blacklisted-skill/SKILL.md" -# Seed a skill in the persistent source that should be restored. -mkdir -p "$SRC_SKILLS/restored-skill" -cat > "$SRC_SKILLS/restored-skill/SKILL.md" <<'EOF' +# Seed a wp-coding-agents skill in the persistent source that should be restored. +mkdir -p "$SRC_SKILLS/upgrade-wp-coding-agents" +cat > "$SRC_SKILLS/upgrade-wp-coding-agents/SKILL.md" <<'EOF' --- -name: restored-skill +name: upgrade-wp-coding-agents description: test fixture --- body EOF +mkdir -p "$SRC_SKILLS/unmanaged-skill" +cat > "$SRC_SKILLS/unmanaged-skill/SKILL.md" <<'EOF' +--- +name: unmanaged-skill +description: unmanaged fixture +--- +body +EOF + mkdir -p "$SRC_SKILLS/persisted-blacklisted-skill" cat > "$SRC_SKILLS/persisted-blacklisted-skill/SKILL.md" <<'EOF' --- @@ -145,9 +154,11 @@ assert_missing "$LIVE_SKILLS/persisted-blacklisted-skill" assert_log_contains "removed skill persisted-blacklisted-skill" assert_log_contains "skipped killed skill persisted-blacklisted-skill" -# Pass 2: skill restore copied the SKILL.md tree. -assert_present "$LIVE_SKILLS/restored-skill/SKILL.md" -assert_log_contains "restored skill restored-skill" +# Pass 2: skill restore copied the allowed SKILL.md tree and skipped unmanaged skills. +assert_present "$LIVE_SKILLS/upgrade-wp-coding-agents/SKILL.md" +assert_log_contains "restored skill upgrade-wp-coding-agents" +assert_missing "$LIVE_SKILLS/unmanaged-skill/SKILL.md" +assert_log_contains "skipped unmanaged skill unmanaged-skill" # Pass 3: default plugin restore is a no-op because opencode loads the # persistent source directly. @@ -213,12 +224,12 @@ FALLBACK_LIVE_SKILLS="$TMP/fallback-live/skills" FALLBACK_LIVE_PLUGINS="$TMP/fallback-live/plugins" mkdir -p \ "$FALLBACK_DATA" \ - "$FALLBACK_HOME/.kimaki/kimaki-config/skills/home-skill" \ + "$FALLBACK_HOME/.kimaki/kimaki-config/skills/wp-coding-agents-setup" \ "$FALLBACK_HOME/.kimaki/kimaki-config/plugins" \ "$FALLBACK_LIVE_SKILLS" -cat > "$FALLBACK_HOME/.kimaki/kimaki-config/skills/home-skill/SKILL.md" <<'EOF' +cat > "$FALLBACK_HOME/.kimaki/kimaki-config/skills/wp-coding-agents-setup/SKILL.md" <<'EOF' --- -name: home-skill +name: wp-coding-agents-setup description: fallback fixture --- body @@ -233,7 +244,7 @@ KIMAKI_DATA_DIR="$FALLBACK_DATA" \ KIMAKI_SKILLS_DIR="$FALLBACK_LIVE_SKILLS" \ "$TEST_SCRIPT_DIR/post-upgrade.sh" > "$TMP/run4.log" 2>&1 -if [[ ! -f "$FALLBACK_LIVE_SKILLS/home-skill/SKILL.md" ]]; then +if [[ ! -f "$FALLBACK_LIVE_SKILLS/wp-coding-agents-setup/SKILL.md" ]]; then echo "FAIL: missing KIMAKI_DATA_DIR skills source should fall through to HOME source" cat "$TMP/run4.log" exit 1 @@ -243,7 +254,7 @@ if [[ -e "$FALLBACK_LIVE_PLUGINS" ]]; then cat "$TMP/run4.log" exit 1 fi -if ! grep -q "restored skill home-skill" "$TMP/run4.log"; then +if ! grep -q "restored skill wp-coding-agents-setup" "$TMP/run4.log"; then echo "FAIL: fallback run should restore the HOME-backed skill" cat "$TMP/run4.log" exit 1 diff --git a/upgrade.sh b/upgrade.sh index 0794908..a0d031e 100755 --- a/upgrade.sh +++ b/upgrade.sh @@ -18,7 +18,7 @@ # reminds user to `npm update -g cc-connect`. # telegram: no per-install artifacts; reports binary versions and # reminds user to `npm update -g @grinev/opencode-telegram-bot`. -# 4. Sync agent skills (WordPress + Data Machine) +# 4. Sync wp-coding-agents skills # 5. Regenerate AGENTS.md via Data Machine compose # 6. Smart systemd update (VPS only; dispatches per bridge) # kimaki → kimaki.service @@ -35,7 +35,7 @@ # ./upgrade.sh --dry-run # preview without changes # ./upgrade.sh --kimaki-only # only sync kimaki config + plugins # ./upgrade.sh --plugins-only # only update Data Machine plugins -# ./upgrade.sh --skills-only # only sync skills +# ./upgrade.sh --skills-only # only sync wp-coding-agents skills # ./upgrade.sh --agents-md-only # only regenerate AGENTS.md # ./upgrade.sh --local --wp-path # local install (auto on macOS) # @@ -141,7 +141,7 @@ USAGE: backwards compat — also handles cc-connect and telegram when they are the detected bridge) ./upgrade.sh --plugins-only Only update setup-installed Data Machine plugins - ./upgrade.sh --skills-only Only sync agent skills + ./upgrade.sh --skills-only Only sync wp-coding-agents skills ./upgrade.sh --agents-md-only Only regenerate AGENTS.md ./upgrade.sh --skip-plugins Skip Data Machine plugin updates during full run ./upgrade.sh --repair-opencode-json @@ -501,19 +501,17 @@ check_opencode_json_drift() { } # ============================================================================ -# Phase 4: Sync agent skills (WordPress + Data Machine) +# Phase 4: Sync wp-coding-agents skills # ============================================================================ sync_skills() { _run_filter_active skills || return 0 - log "Phase 4: Syncing agent skills..." + log "Phase 4: Syncing wp-coding-agents skills..." if [ "$DRY_RUN" = true ]; then SKILLS_DIR="$(runtime_skills_dir)" echo -e "${BLUE}[dry-run]${NC} Would install in-repo skills from $SCRIPT_DIR/skills → $SKILLS_DIR" - echo -e "${BLUE}[dry-run]${NC} Would clone WordPress/agent-skills → $SKILLS_DIR" - echo -e "${BLUE}[dry-run]${NC} Would clone Extra-Chill/data-machine-skills → $SKILLS_DIR" if [ "$CHAT_BRIDGE" = "kimaki" ]; then echo -e "${BLUE}[dry-run]${NC} Would copy skills to kimaki skills dir" fi @@ -521,7 +519,7 @@ sync_skills() { fi install_skills - UPDATED_ITEMS+=("agent skills") + UPDATED_ITEMS+=("wp-coding-agents skills") } # ============================================================================