From 3628d88cd565271ae69a3624942883d310817d39 Mon Sep 17 00:00:00 2001 From: DenisSaramelo Date: Mon, 17 Aug 2026 21:23:32 -0300 Subject: [PATCH] fix: make the plugin actually load in Claude Code Nothing shipped by this repo was reaching Claude Code: `/grow` never registered, and neither did any of the agents. Three separate defects, all confirmed by `claude plugin validate`: 1. Invalid manifest. `.claude-plugin/plugin.json` declared `commands`, `agents`, `skills` and `hooks` as arrays of objects (`[{"path": "..."}]`), a shape the schema rejects, plus `mcp-servers` instead of `mcpServers`: plugins[0] plugin.json -> hooks: Invalid input plugins[0] plugin.json -> commands: Invalid input plugins[0] plugin.json -> agents: Invalid input plugins[0] plugin.json -> skills: Invalid input 2. Wrong file layout. Claude Code discovers components by convention: `commands/.md`, `agents/.md`, `skills//SKILL.md`. This repo had `commands/grow/COMMAND.md` and `agents//AGENT.md`, so zero commands and zero agents were discovered. Pointing the manifest at those paths explicitly passes validation but still loads no agents -- only the conventional layout works. 3. Unsupported install method. `install.sh` symlinked the clone into `~/.claude/plugins/growthOS`. That directory is Claude Code's own managed state (cache/, marketplaces/, installed_plugins.json), not a discovery path, so the symlink did nothing. A plugin is discovered only once it is registered as a marketplace and installed from it -- and this repo already ships `.claude-plugin/marketplace.json` for exactly that. Changes: - `commands/grow/COMMAND.md` -> `commands/grow.md`; the supporting docs (`setup.md`, `FREE-CONTENT.md`) move to `docs/grow/`, references updated. - `agents//AGENT.md` -> `agents/.md`; per-agent `README.md` and `router.md` move to `docs/agents//`. - Manifest reduced to the valid schema, relying on convention-based discovery. The duplicate root `plugin.json` is removed: Claude Code reads only `.claude-plugin/plugin.json`, and the two had already drifted apart (11 agents/26 skills vs 9/20). - `install.sh` rewritten around `claude plugin marketplace add` + `claude plugin install`, validating the manifest first and cleaning up the symlink older versions left behind. - README: installation, uninstall and troubleshooting rewritten around commands that report real state (`claude plugin list|details|validate`); architecture tree corrected. Verified with `claude plugin details growthOS`: Skills (27) ... grow ... Agents (12) cmo, caption-writer, content-creator, ... Still not wired, out of scope here: the four `hooks/*.md` are prose, not hook configuration, and the MCP servers have no `mcpServers` entry -- both report (0). Co-Authored-By: Claude Opus 5 --- .claude-plugin/plugin.json | 52 +----------- README.md | 73 ++++++++++++----- agents/README.md | 3 - .../AGENT.md => caption-writer.md} | 0 .../AGENT.md => carousel-designer.md} | 0 agents/{cmo/AGENT.md => cmo.md} | 0 .../AGENT.md => content-creator.md} | 0 .../AGENT.md => growth-engineer.md} | 0 .../AGENT.md => growth-strategist.md} | 0 .../AGENT.md => intelligence-analyst.md} | 0 .../AGENT.md => sales-page-architect.md} | 0 .../AGENT.md => sales-page-qa.md} | 0 .../AGENT.md => social-publisher.md} | 0 .../AGENT.md => video-producer.md} | 0 .../AGENT.md => visual-designer.md} | 0 commands/README.md | 1 - commands/{grow/COMMAND.md => grow.md} | 2 +- commands/grow/README.md | 1 - .../agents}/carousel-designer/README.md | 0 {agents => docs/agents}/cmo/README.md | 0 {agents => docs/agents}/cmo/router.md | 0 .../agents}/content-creator/README.md | 0 .../agents}/growth-engineer/README.md | 0 .../agents}/growth-strategist/README.md | 0 .../agents}/intelligence-analyst/README.md | 0 .../agents}/social-publisher/README.md | 0 .../agents}/video-producer/README.md | 0 .../agents}/visual-designer/README.md | 0 {commands => docs}/grow/FREE-CONTENT.md | 0 {commands => docs}/grow/setup.md | 0 docs/guides/ARCHITECTURE-GUIDE.md | 4 +- docs/qa/GROWTHOS-TEST-PLAN.md | 2 +- install.sh | 80 ++++++++++--------- plugin.json | 64 --------------- 34 files changed, 98 insertions(+), 184 deletions(-) delete mode 100644 agents/README.md rename agents/{caption-writer/AGENT.md => caption-writer.md} (100%) rename agents/{carousel-designer/AGENT.md => carousel-designer.md} (100%) rename agents/{cmo/AGENT.md => cmo.md} (100%) rename agents/{content-creator/AGENT.md => content-creator.md} (100%) rename agents/{growth-engineer/AGENT.md => growth-engineer.md} (100%) rename agents/{growth-strategist/AGENT.md => growth-strategist.md} (100%) rename agents/{intelligence-analyst/AGENT.md => intelligence-analyst.md} (100%) rename agents/{sales-page-architect/AGENT.md => sales-page-architect.md} (100%) rename agents/{sales-page-qa/AGENT.md => sales-page-qa.md} (100%) rename agents/{social-publisher/AGENT.md => social-publisher.md} (100%) rename agents/{video-producer/AGENT.md => video-producer.md} (100%) rename agents/{visual-designer/AGENT.md => visual-designer.md} (100%) delete mode 100644 commands/README.md rename commands/{grow/COMMAND.md => grow.md} (99%) delete mode 100644 commands/grow/README.md rename {agents => docs/agents}/carousel-designer/README.md (100%) rename {agents => docs/agents}/cmo/README.md (100%) rename {agents => docs/agents}/cmo/router.md (100%) rename {agents => docs/agents}/content-creator/README.md (100%) rename {agents => docs/agents}/growth-engineer/README.md (100%) rename {agents => docs/agents}/growth-strategist/README.md (100%) rename {agents => docs/agents}/intelligence-analyst/README.md (100%) rename {agents => docs/agents}/social-publisher/README.md (100%) rename {agents => docs/agents}/video-producer/README.md (100%) rename {agents => docs/agents}/visual-designer/README.md (100%) rename {commands => docs}/grow/FREE-CONTENT.md (100%) rename {commands => docs}/grow/setup.md (100%) delete mode 100644 plugin.json diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 132716c..31c862c 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,58 +1,10 @@ { "name": "growthOS", "version": "1.0.0", - "description": "Autonomous marketing team for Claude Code — 9 AI agents, 20 skills, 4 MCP servers, one /grow command", + "description": "Autonomous marketing team for Claude Code — 12 AI agents, 26 skills, 4 MCP servers, one /grow command", "author": { "name": "GrowthOS Community" }, "license": "MIT", - "repository": "https://github.com/melgarafael/growthOS", - "skills": [ - {"path": "skills/marketing-strategy"}, - {"path": "skills/copywriting"}, - {"path": "skills/seo-growth"}, - {"path": "skills/content-creation"}, - {"path": "skills/social-media-management"}, - {"path": "skills/competitive-intelligence"}, - {"path": "skills/video-production"}, - {"path": "skills/landing-page-design"}, - {"path": "skills/platform-mastery"}, - {"path": "skills/instagram-carousel"}, - {"path": "skills/remotion-video"}, - {"path": "skills/remotion-pro"}, - {"path": "skills/showcase-before-after"}, - {"path": "skills/showcase-course-trailer"}, - {"path": "skills/showcase-data-story"}, - {"path": "skills/showcase-feature-highlight"}, - {"path": "skills/showcase-product-demo"}, - {"path": "skills/showcase-social-proof"}, - {"path": "skills/showcase-tech-terminal"}, - {"path": "skills/showcase-walkthrough"} - ], - "agents": [ - {"path": "agents/cmo"}, - {"path": "agents/growth-strategist"}, - {"path": "agents/content-creator"}, - {"path": "agents/intelligence-analyst"}, - {"path": "agents/visual-designer"}, - {"path": "agents/social-publisher"}, - {"path": "agents/growth-engineer"}, - {"path": "agents/carousel-designer"}, - {"path": "agents/video-producer"} - ], - "hooks": [ - {"path": "hooks/audit-logger.md"}, - {"path": "hooks/circuit-breaker.md"}, - {"path": "hooks/preview-before-publish.md"}, - {"path": "hooks/dry-run-guard.md"} - ], - "commands": [ - {"path": "commands/grow"} - ], - "mcp-servers": [ - {"path": "mcp-servers/mcp-social-publish"}, - {"path": "mcp-servers/mcp-social-discover"}, - {"path": "mcp-servers/mcp-obsidian-vault"}, - {"path": "mcp-servers/mcp-remotion-render"} - ] + "repository": "https://github.com/melgarafael/growthOS" } diff --git a/README.md b/README.md index 0e30557..1ce811b 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,9 @@ GrowthOS turns Claude Code into a full-stack growth engine: strategy, content cr ## Installation -> GrowthOS is distributed **only via `git clone`** — it is not published on the Claude Code marketplace. The `install.sh` script wires the cloned repo into `~/.claude/plugins/growthOS` so Claude Code discovers every skill, agent, command, and hook as a real slash command (`/grow`, `/growthOS:`). +> GrowthOS is distributed **only via `git clone`** — it is not published on the public Claude Code marketplace. The repo ships its own **local marketplace manifest** (`.claude-plugin/marketplace.json`), and `install.sh` registers it and installs the plugin from it, so Claude Code discovers every skill, agent and command as a real slash command (`/grow`, `/growthOS:`). +> +> Dropping the repo (or a symlink to it) into `~/.claude/plugins/` does **not** work — that directory is Claude Code's own managed state, not a discovery path. ### What do I need to install? @@ -47,7 +49,10 @@ cd growthOS What the installer does: -- Creates a symlink `~/.claude/plugins/growthOS → ` (standard Claude Code plugin discovery path). +- Validates the manifests (`claude plugin validate .`) and aborts if they are malformed. +- Registers the clone as a local marketplace (`claude plugin marketplace add `). +- Installs the plugin from it (`claude plugin install growthOS@growthOS`). +- Removes the obsolete `~/.claude/plugins/growthOS` symlink left by older installers. - Copies `brand-voice.example.yaml` → `brand-voice.yaml` if you don't have one yet. - Prints next steps. @@ -94,17 +99,30 @@ It writes to `brand-voice.yaml`, which all agents read to stay on-brand. That fi ### Uninstall ```bash -rm ~/.claude/plugins/growthOS +claude plugin uninstall growthOS@growthOS +claude plugin marketplace remove growthOS ``` ### Troubleshooting — slash commands not showing up If `/grow` or `/growthOS:` do not appear after install: -1. Confirm the symlink exists: `ls -la ~/.claude/plugins/growthOS` -2. Confirm the manifest: `cat ~/.claude/plugins/growthOS/.claude-plugin/plugin.json` -3. Fully restart Claude Code (not just reload — exit the session and reopen). -4. Inside Claude Code, run `/help` to list loaded plugins. +1. Confirm the plugin is installed **and enabled**: `claude plugin list` — you should see `growthOS@growthOS` with `Status: enabled`. +2. Confirm what actually loaded: `claude plugin details growthOS` — it must list `grow` plus the agents and skills. If a section shows `(0)`, the manifest or the file layout is wrong, not the install. +3. Validate the manifests: `claude plugin validate .` — it must pass. +4. Fully restart Claude Code (not just reload — exit the session and reopen). + +**After editing this repo**, the installed copy is a snapshot under `~/.claude/plugins/cache/` and does not track your edits. Re-sync it: + +```bash +claude plugin marketplace update growthOS && claude plugin update growthOS@growthOS +# if the version did not change, the update is a no-op — reinstall instead: +claude plugin uninstall growthOS@growthOS && claude plugin install growthOS@growthOS -y +``` + +**File layout matters.** Claude Code discovers components by convention: +`commands/.md`, `agents/.md`, `skills//SKILL.md`. +A command at `commands/grow/COMMAND.md` does **not** register as `/grow`. --- @@ -239,22 +257,27 @@ Or just run `/grow setup` and the wizard handles it for you. ``` growthOS/ -├── plugin.json # Plugin manifest (entry point) +├── .claude-plugin/ +│ ├── plugin.json # Plugin manifest (what Claude Code reads) +│ └── marketplace.json # Local marketplace used by install.sh ├── brand-voice.example.yaml # Brand config template ├── .env.example # Environment variables template │ -├── agents/ # 9 AI agents -│ ├── cmo/ # CMO — intent router -│ ├── growth-strategist/ # Strategic planning -│ ├── content-creator/ # Content production -│ ├── intelligence-analyst/ # Competitive intel -│ ├── visual-designer/ # Visual assets -│ ├── social-publisher/ # Social media ops -│ ├── growth-engineer/ # Technical growth -│ ├── carousel-designer/ # Carousel generation -│ └── video-producer/ # Video production +├── agents/ # 12 AI agents (one .md per agent) +│ ├── cmo.md # CMO — intent router +│ ├── growth-strategist.md # Strategic planning +│ ├── content-creator.md # Content production +│ ├── intelligence-analyst.md # Competitive intel +│ ├── visual-designer.md # Visual assets +│ ├── social-publisher.md # Social media ops +│ ├── growth-engineer.md # Technical growth +│ ├── carousel-designer.md # Carousel generation +│ ├── caption-writer.md # Instagram captions +│ ├── sales-page-architect.md # Sales page structure +│ ├── sales-page-qa.md # Sales page QA +│ └── video-producer.md # Video production │ -├── skills/ # 20 specialized skills +├── skills/ # 26 specialized skills │ ├── marketing-strategy/ # Core skills (11) │ ├── copywriting/ │ ├── seo-growth/ @@ -274,7 +297,13 @@ growthOS/ │ ├── showcase-product-demo/ │ ├── showcase-social-proof/ │ ├── showcase-tech-terminal/ -│ └── showcase-walkthrough/ +│ ├── showcase-walkthrough/ +│ ├── sales-page/ # Sales page system (6) +│ ├── sales-page-discovery/ +│ ├── sales-page-research/ +│ ├── sales-page-visual-psychology/ +│ ├── sales-page-narrative/ +│ └── sales-page-builder/ │ ├── mcp-servers/ # 4 MCP servers (Python/FastMCP) │ ├── mcp-social-publish/ # Publish to 5 platforms @@ -299,8 +328,8 @@ growthOS/ │ ├── preview-before-publish.md# Preview before sending │ └── dry-run-guard.md # Block real calls in dry-run │ -├── commands/ # CLI commands -│ └── grow/ # /grow entry point + setup +├── commands/ # Slash commands (one .md per command) +│ └── grow.md # /grow entry point │ ├── remotion/ # Video rendering engine │ └── src/ diff --git a/agents/README.md b/agents/README.md deleted file mode 100644 index 06f0597..0000000 --- a/agents/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# GrowthOS Agents - -AI agent definitions for the autonomous marketing team — CMO, strategist, copywriter, designer, and more. diff --git a/agents/caption-writer/AGENT.md b/agents/caption-writer.md similarity index 100% rename from agents/caption-writer/AGENT.md rename to agents/caption-writer.md diff --git a/agents/carousel-designer/AGENT.md b/agents/carousel-designer.md similarity index 100% rename from agents/carousel-designer/AGENT.md rename to agents/carousel-designer.md diff --git a/agents/cmo/AGENT.md b/agents/cmo.md similarity index 100% rename from agents/cmo/AGENT.md rename to agents/cmo.md diff --git a/agents/content-creator/AGENT.md b/agents/content-creator.md similarity index 100% rename from agents/content-creator/AGENT.md rename to agents/content-creator.md diff --git a/agents/growth-engineer/AGENT.md b/agents/growth-engineer.md similarity index 100% rename from agents/growth-engineer/AGENT.md rename to agents/growth-engineer.md diff --git a/agents/growth-strategist/AGENT.md b/agents/growth-strategist.md similarity index 100% rename from agents/growth-strategist/AGENT.md rename to agents/growth-strategist.md diff --git a/agents/intelligence-analyst/AGENT.md b/agents/intelligence-analyst.md similarity index 100% rename from agents/intelligence-analyst/AGENT.md rename to agents/intelligence-analyst.md diff --git a/agents/sales-page-architect/AGENT.md b/agents/sales-page-architect.md similarity index 100% rename from agents/sales-page-architect/AGENT.md rename to agents/sales-page-architect.md diff --git a/agents/sales-page-qa/AGENT.md b/agents/sales-page-qa.md similarity index 100% rename from agents/sales-page-qa/AGENT.md rename to agents/sales-page-qa.md diff --git a/agents/social-publisher/AGENT.md b/agents/social-publisher.md similarity index 100% rename from agents/social-publisher/AGENT.md rename to agents/social-publisher.md diff --git a/agents/video-producer/AGENT.md b/agents/video-producer.md similarity index 100% rename from agents/video-producer/AGENT.md rename to agents/video-producer.md diff --git a/agents/visual-designer/AGENT.md b/agents/visual-designer.md similarity index 100% rename from agents/visual-designer/AGENT.md rename to agents/visual-designer.md diff --git a/commands/README.md b/commands/README.md deleted file mode 100644 index 99d19b6..0000000 --- a/commands/README.md +++ /dev/null @@ -1 +0,0 @@ -# GrowthOS Commands diff --git a/commands/grow/COMMAND.md b/commands/grow.md similarity index 99% rename from commands/grow/COMMAND.md rename to commands/grow.md index df3af16..a245452 100644 --- a/commands/grow/COMMAND.md +++ b/commands/grow.md @@ -475,7 +475,7 @@ Quando o UiUX Expert terminar, o arquivo novo aparece em `design-system/` e voc #### Subcommand: `free-content` **Syntax:** `/grow free-content [source]` -**Docs:** `growthOS/commands/grow/FREE-CONTENT.md` +**Docs:** `growthOS/docs/grow/FREE-CONTENT.md` Bridge from Educational Team (TIM) to GrowthOS. Dispatches `Orquestrador - Educational team` via Maestri to transcribe a lesson/video and extract viral chunks, then pipes each chunk into the normal carousel pipeline via `content-factory` skill. diff --git a/commands/grow/README.md b/commands/grow/README.md deleted file mode 100644 index fa65156..0000000 --- a/commands/grow/README.md +++ /dev/null @@ -1 +0,0 @@ -# grow diff --git a/agents/carousel-designer/README.md b/docs/agents/carousel-designer/README.md similarity index 100% rename from agents/carousel-designer/README.md rename to docs/agents/carousel-designer/README.md diff --git a/agents/cmo/README.md b/docs/agents/cmo/README.md similarity index 100% rename from agents/cmo/README.md rename to docs/agents/cmo/README.md diff --git a/agents/cmo/router.md b/docs/agents/cmo/router.md similarity index 100% rename from agents/cmo/router.md rename to docs/agents/cmo/router.md diff --git a/agents/content-creator/README.md b/docs/agents/content-creator/README.md similarity index 100% rename from agents/content-creator/README.md rename to docs/agents/content-creator/README.md diff --git a/agents/growth-engineer/README.md b/docs/agents/growth-engineer/README.md similarity index 100% rename from agents/growth-engineer/README.md rename to docs/agents/growth-engineer/README.md diff --git a/agents/growth-strategist/README.md b/docs/agents/growth-strategist/README.md similarity index 100% rename from agents/growth-strategist/README.md rename to docs/agents/growth-strategist/README.md diff --git a/agents/intelligence-analyst/README.md b/docs/agents/intelligence-analyst/README.md similarity index 100% rename from agents/intelligence-analyst/README.md rename to docs/agents/intelligence-analyst/README.md diff --git a/agents/social-publisher/README.md b/docs/agents/social-publisher/README.md similarity index 100% rename from agents/social-publisher/README.md rename to docs/agents/social-publisher/README.md diff --git a/agents/video-producer/README.md b/docs/agents/video-producer/README.md similarity index 100% rename from agents/video-producer/README.md rename to docs/agents/video-producer/README.md diff --git a/agents/visual-designer/README.md b/docs/agents/visual-designer/README.md similarity index 100% rename from agents/visual-designer/README.md rename to docs/agents/visual-designer/README.md diff --git a/commands/grow/FREE-CONTENT.md b/docs/grow/FREE-CONTENT.md similarity index 100% rename from commands/grow/FREE-CONTENT.md rename to docs/grow/FREE-CONTENT.md diff --git a/commands/grow/setup.md b/docs/grow/setup.md similarity index 100% rename from commands/grow/setup.md rename to docs/grow/setup.md diff --git a/docs/guides/ARCHITECTURE-GUIDE.md b/docs/guides/ARCHITECTURE-GUIDE.md index d1de997..7f7c8b0 100644 --- a/docs/guides/ARCHITECTURE-GUIDE.md +++ b/docs/guides/ARCHITECTURE-GUIDE.md @@ -83,7 +83,7 @@ produzir scripts de video e orquestrar campanhas -- tudo a partir de linguagem n v +------------------------------+ | COMMAND INTERFACE | - | commands/grow/COMMAND.md | + | commands/grow.md | | | | 1. First-run detection | | 2. Parse argumentos | @@ -219,7 +219,7 @@ produzir scripts de video e orquestrar campanhas -- tudo a partir de linguagem n ### Camada 1: Command Interface -**Localizacao:** `commands/grow/COMMAND.md` +**Localizacao:** `commands/grow.md` A camada de entrada do sistema. O comando `/grow` e o unico ponto de interacao do usuario com o GrowthOS. diff --git a/docs/qa/GROWTHOS-TEST-PLAN.md b/docs/qa/GROWTHOS-TEST-PLAN.md index e7f2ce4..4da93a7 100644 --- a/docs/qa/GROWTHOS-TEST-PLAN.md +++ b/docs/qa/GROWTHOS-TEST-PLAN.md @@ -244,7 +244,7 @@ ### Verificacoes: 1. CMO router.md referencia agentes que existem em agents/ 2. COMMAND.md subcommands delegam a agentes que existem -3. plugin.json commands[] → commands/grow/ existe +3. plugin.json por convenção → commands/grow.md existe 4. plugin.json skills[] → skills/*/ existem 5. plugin.json agents[] → agents/*/ existem 6. plugin.json hooks[] → hooks/*.md existem diff --git a/install.sh b/install.sh index b4798c9..f7158db 100755 --- a/install.sh +++ b/install.sh @@ -3,13 +3,13 @@ # GrowthOS installer # # Why this exists: -# GrowthOS is distributed as a git repo (NOT via the Claude -# Code marketplace). Cloning alone is not enough — Claude Code -# only discovers plugins that live inside its plugin directory -# (~/.claude/plugins/). This script symlinks the -# cloned repo into that directory so all skills, agents, -# commands and hooks become available as slash commands like -# /grow and /growthOS:. +# Claude Code does NOT discover plugins by their presence in +# ~/.claude/plugins/ — that directory is Claude Code's +# own managed state (cache/, marketplaces/, installed_plugins.json). +# A plugin is discovered only when it is registered as a +# marketplace and installed from it. This repo ships its own +# local marketplace manifest (.claude-plugin/marketplace.json), +# so the two commands below are all that is needed. # # Usage: # git clone https://github.com/melgarafael/growthOS.git @@ -20,13 +20,10 @@ set -euo pipefail REPO_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -PLUGIN_NAME="growthOS" -CLAUDE_PLUGINS_DIR="${HOME}/.claude/plugins" -TARGET="${CLAUDE_PLUGINS_DIR}/${PLUGIN_NAME}" +PLUGIN_ID="growthOS@growthOS" echo "→ GrowthOS installer" -echo " repo: ${REPO_DIR}" -echo " target: ${TARGET}" +echo " repo: ${REPO_DIR}" echo # Sanity: must be run from inside the repo @@ -35,28 +32,28 @@ if [[ ! -f "${REPO_DIR}/.claude-plugin/plugin.json" ]]; then exit 1 fi -mkdir -p "${CLAUDE_PLUGINS_DIR}" - -# If target already exists, handle gracefully -if [[ -L "${TARGET}" ]]; then - CURRENT="$(readlink "${TARGET}")" - if [[ "${CURRENT}" == "${REPO_DIR}" ]]; then - echo "✓ already linked to this repo — nothing to do." - exit 0 - fi - echo "! ${TARGET} is a symlink pointing elsewhere (${CURRENT})." - read -r -p " replace it? [y/N] " ans - [[ "${ans}" =~ ^[Yy]$ ]] || { echo "aborted."; exit 1; } - rm "${TARGET}" -elif [[ -e "${TARGET}" ]]; then - echo "! ${TARGET} already exists and is not a symlink." - read -r -p " back it up to ${TARGET}.bak and replace? [y/N] " ans - [[ "${ans}" =~ ^[Yy]$ ]] || { echo "aborted."; exit 1; } - mv "${TARGET}" "${TARGET}.bak" +if ! command -v claude >/dev/null 2>&1; then + echo "✗ the 'claude' CLI is not on PATH — install Claude Code first." >&2 + exit 1 +fi + +# Fail fast on a malformed manifest instead of installing something broken +echo "→ validating manifests…" +claude plugin validate "${REPO_DIR}" + +# Remove the symlink left behind by older versions of this installer +LEGACY_LINK="${HOME}/.claude/plugins/growthOS" +if [[ -L "${LEGACY_LINK}" ]]; then + rm "${LEGACY_LINK}" + echo "✓ removed legacy symlink ${LEGACY_LINK} (no longer used)" fi -ln -s "${REPO_DIR}" "${TARGET}" -echo "✓ linked ${TARGET} → ${REPO_DIR}" +echo "→ registering local marketplace…" +claude plugin marketplace add "${REPO_DIR}" --scope user 2>&1 | tail -1 || true +claude plugin marketplace update growthOS >/dev/null 2>&1 || true + +echo "→ installing plugin…" +claude plugin install "${PLUGIN_ID}" --scope user -y # Copy brand-voice template if user has not set one yet if [[ ! -f "${REPO_DIR}/brand-voice.yaml" && -f "${REPO_DIR}/brand-voice.example.yaml" ]]; then @@ -70,19 +67,24 @@ cat <