Ship a `.claude-plugin/` manifest so the skill installs via `/plugin marketplace add`

Author: BordaCreated Aug 24, 2026Updated Aug 24, 2026

Summary

geo-seo-claude currently ships only as a shell installer. There is no .claude-plugin/plugin.json, so /plugin marketplace add zubair-trabzada/geo-seo-claude cannot resolve the repo and users have to clone (or pipe curl into bash) to get anything installed.

The blocker is not just the missing manifest. install.sh performs content mutation that the skill depends on to function, so the repo as checked out is not runnable. Adding a manifest without addressing that would produce a plugin install that silently does nothing useful.

I would like to fix both, but the work touches layout and the install story, so I would rather agree on scope here before opening PRs.

What install.sh rewrites today

Two sed passes, both load-bearing:

bash
# scripts/*.py — shebang pinned to the venv interpreter
sed_inplace "1s|^#!.*|#!${VENV_PY}|" "$f"

# SKILL.md and agents/geo-*.md — inline python calls repointed at the venv
sed_inplace 's|python3 ~/\.claude/skills/geo/scripts/|~/.claude/skills/geo/scripts/|g' "$f"
sed_inplace "s|python3 -c |${VENV_MD_PY} -c |g" "$f"
sed_inplace "s|python3 -m |${VENV_MD_PY} -m |g" "$f"

Because the correct paths only exist post-install, a few things follow:

  • The install is not relocatable. Moving ~/.claude breaks every patched reference.
  • VENV_PY resolves to .venv/bin/python3, which is POSIX-only. That is why Windows support is Git Bash rather than native PowerShell.
  • There is no clean upgrade path — updating means removing the venv, re-cloning, and re-running the patch pass.
  • git diff between the repo and an installed copy is meaningless, which makes user bug reports harder to reproduce.

The root cause of all of it is hardcoded absolute paths in SKILL.md and the agent files where ${CLAUDE_PLUGIN_ROOT} belongs. Removing those makes the patching layer unnecessary rather than merely simplified.

Proposed change

1. Manifest and layout. Add .claude-plugin/plugin.json and .claude-plugin/marketplace.json, and move the orchestrator from geo/SKILL.md into skills/geo/ so the loader discovers it alongside the existing skills/geo-*/ sub-skills.

2. Path migration. Replace hardcoded ~/.claude/skills/geo/... references in SKILL.md, skills/geo-*/SKILL.md, and agents/geo-*.md with ${CLAUDE_PLUGIN_ROOT}/.... This deletes patch_md() and the shebang loop outright.

3. Managed runtime. Add a small launcher (bin/geo plus scripts/runtime.py) with setup / doctor / run subcommands. setup provisions the venv under ${CLAUDE_PLUGIN_DATA} with a platform-data-dir fallback and picks Scripts/python.exe on Windows; run executes a bundled script through the venv interpreter and exits non-zero with a pointer to /geo setup when the runtime is missing, rather than provisioning implicitly. Expose it as a /geo setup command, with Playwright Chromium as an explicit flag instead of an interactive prompt.

4. Runtime data. ~/.geo-prospects/ currently survives uninstall, which the README documents but users are unlikely to expect. Moving it under ${CLAUDE_PLUGIN_DATA} would fix that, with a read-and-migrate path for existing directories so no prospect data is lost. Happy to drop this item if you would rather keep prospect data outside the plugin lifecycle on purpose.

5. Installer. With the above in place, install.sh becomes a thin fallback for non-plugin users, or can be dropped entirely. Your call. If it stays, pinning git clone --depth 1 --branch <tag> instead of tracking main would stop installs from picking up unreleased commits, and the README could recommend download-inspect-run over curl ... | bash.

Scope and sequencing

I would split this into three reviewable PRs rather than one large one:

  1. Manifest plus the geo/skills/geo/ move, with history preserved.
  2. ${CLAUDE_PLUGIN_ROOT} migration and the runtime launcher, removing both sed passes.
  3. Data-directory migration and installer slimming.

Each is independently revertible, and (1) alone already makes /plugin marketplace add work.

No command names or behaviour would change — this is a packaging refactor, not a feature change. I would leave README copy and the community links alone.

Verification I plan to run before opening anything: /plugin marketplace add ./ from a local checkout followed by /plugin install and /geo setup, then at least one real command end to end, on both macOS/Linux and native Windows PowerShell, plus a check that no file in the repo is mutated by installation.

Questions

  • Is the plugin-manifest direction something you want, or is the shell installer a deliberate choice?
  • Do you want install.sh kept as a fallback, or removed once the plugin path works?
  • Should ~/.geo-prospects/ stay outside the plugin data directory?

Happy to start with PR 1 on its own so you can see the shape before committing to the rest.

Source: zubair-trabzada/geo-seo-claude