power-pages-liquid-js-plugin
A Claude Code plugin that stops Claude from writing Shopify Liquid syntax into Microsoft Power Pages Liquid templates.
Why
Power Pages Liquid is a DotLiquid-based dialect that talks to Dataverse. It shares the base Liquid grammar with Shopify but has a completely different tag/object/filter vocabulary. Because Shopify Liquid dominates training data, Claude reliably reaches for {% paginate %}, {% section %}, {% schema %}, product.*, | asset_url, | money, etc. — none of which exist in Power Pages.
This plugin provides a two-layer defense:
| Layer | Component | Role |
|---|
| Proactive | skills/power-pages-liquid | Loads Power Pages tag / object / filter reference whenever Claude touches .liquid files. |
| Reactive | hooks/hooks.json → scripts/pp-liquid-guard.sh (PreToolUse) | Hard-blocks Write/Edit/MultiEdit on .liquid files that contain Shopify syntax. The stderr message names every offender and the Power Pages replacement, so Claude self-corrects on retry. |
| Audit | /pp-liquid-lint [path] slash command | On-demand scan of existing files (e.g. AI-generated code already on disk). |
Install
Local (current machine)
From any Claude Code session, point the marketplace at this directory and install the plugin:
/plugin marketplace add /home/marty/code-projects/power-pages-liquid-js-plugin
/plugin install power-pages-liquid
(Exact command syntax depends on your Claude Code version — use /plugin and follow the prompts if these don't match.)
From GitHub
After pushing this repo to GitHub:
/plugin marketplace add <github-org>/power-pages-liquid-js-plugin
/plugin install power-pages-liquid
Dependencies
The hook uses jq and grep. jq is the only one you may need to install:
# Debian / Ubuntu
sudo apt-get install jq
# macOS
brew install jq
If jq is missing the hook fails open (logs a warning, allows the write) so it never blocks your work over a missing dep.
What it catches
The hook and /pp-liquid-lint share one source of truth: scripts/lib/shopify-patterns.txt. Every entry has a regex, a friendly offender label, and a Power Pages fix hint.
Current coverage:
- Shopify-only tags —
{% paginate %}, {% section %}, {% sections %}, {% schema %}, {% layout %}, {% form '...' %}, {% style %}, {% javascript %}, {% render '...' %}
- Shopify-only objects —
product.*, products[...], collection.*, collections[...], cart.*, customer.*, shop.*, linklists.*, block.settings, section.settings
- Shopify-only filters —
| asset_url, | asset_img_url, | img_url, | img_tag, | money, | money_with_currency, | money_without_currency, | money_without_trailing_zeros, | weight_with_unit, | stylesheet_tag, | script_tag, | handleize, | handle, | within
See skills/power-pages-liquid/references/shopify-vs-power-pages.md for the same table with Power Pages replacements.
Usage
Once installed, the plugin works invisibly:
- Ask Claude to add a feature to a
.liquid file → the skill loads automatically.
- If Claude tries to write Shopify syntax, the hook blocks the write and reports each offender with its Power Pages replacement. Claude retries with the right syntax.
- Run
/pp-liquid-lint (or /pp-liquid-lint web-templates/) to audit existing files.
Disabling the hook temporarily
If you need to write a .liquid file that legitimately should not be linted (rare):
- Quickest:
/plugin disable power-pages-liquid, do the work, then re-enable.
- Surgical: rename
hooks/hooks.json to hooks/hooks.json.disabled and restart your session.
(A {# pp-lint:allow ... #} inline escape hatch is an obvious follow-up if false positives become a problem in practice. Not implemented in v0.1.)
Extending the pattern catalog
Spot a Shopify-ism Claude keeps emitting that isn't caught yet? Add a TAB-separated row to scripts/lib/shopify-patterns.txt:
category<TAB>regex<TAB>offender_label<TAB>fix_hint
category is one of tag, obj, filter (used only for display grouping; anything else also works).
regex is ERE (grep -E) — use [[:space:]] for whitespace and escape { / }.
offender_label is what the block message prints in the OFFENDER column.
fix_hint is the Power Pages replacement (one line).
Then also update skills/power-pages-liquid/references/shopify-vs-power-pages.md so the skill stays in sync with the hook.
Layout