product-listing-writerlisted
Install: claude install-skill storehand/storehand
# Product listing writer
Two phases, and they never run in one breath. **Propose** reads the store and
writes a file you edit. **Apply** writes to the store, and only the fields you
left in that file that nobody touched in the admin meanwhile.
Network: your own store's product images (route 4 in shared/safety.md)
**Two kinds of path, do not mix them up.** Files belonging to this plugin —
`shared/*.md`, `queries/`, `mutations/`, `scripts/` — live under the plugin's
install directory. The store profile and the proposals (`.storehand/`) live in
the user's working directory.
## Step 0 — Find the plugin
`$CLAUDE_PLUGIN_ROOT` is empty in the environment of a Bash tool call. That is
measured, not assumed; the working routes and the reasoning are in
`shared/plugin-root.md`. Run this once, before anything else:
```bash
ROOT=$( {
printf '%s\n' "${CLAUDE_PLUGIN_ROOT:-}"
printf '%s' "$PATH" | tr ':' '\n' | sed -n 's|/bin$||p' | grep -E '/storehand/[^/]+$'
node -e 'const fs=require("fs"),os=require("os"),p=require("path");try{const j=JSON.parse(fs.readFileSync(p.join(os.homedir(),".claude","plugins","installed_plugins.json"),"utf8"));for(const[k,v]of Object.entries(j.plugins||{}))if(k.split("@")[0]==="storehand"&&v[0]&&v[0].installPath){console.log(v[0].installPath);break}}catch{}' 2>/dev/null
} | while IFS= read -r c; do
[ -n "$c" ] && [ -f "$c/shared/api-version.md" ] && { printf '%s' "$c"; break; }
done )
[ -n "$ROOT" ] && echo "StoreHand plugin root: $ROOT" || echo "Stor